forked from rogueforge/rogomatic14
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfork_exec.c
More file actions
123 lines (113 loc) · 3.62 KB
/
Copy pathfork_exec.c
File metadata and controls
123 lines (113 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* fork_exec - fork a while process and execute a file
*
* Copyright (c) 2026 by Landon Curt Noll. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright, this permission notice and text
* this comment, and the disclaimer below appear in all of the following:
*
* supporting documentation
* source copies
* source works derived from this source
* binaries derived from this source or from derived source
*
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* chongo (Landon Curt Noll) /\oo/\
*
* http://www.isthe.com/chongo/index.html
* https://github.com/lcn2
*
* Share and enjoy! :-)
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <inttypes.h>
#include "types.h"
#include "config.h"
/*
* fork_exec: fork a while process and execute a command with args
*
* For a child process, and then execute a command (searched for along $PATH), when a list of arguments.
*
* given:
* file - path to file to exec
* arglist - NULL terminated list of args, starting with file (argv[] style)
*
* returns:
* exit code from command
*
* Example:
*
* int ret; (* child exit statis *)
* char *newfil; (* new filename *)
* char *delfil; (* delta filename *)
* char *arglist[] = { (* command to execute and its args, NULL terminated *)
* "sort", "+4nr", "-o", newfil, delfil, NULL
* };
*
* ret = fork_exec("sort", arglist);
* if (ret != 0) {
* quit (1, "ERROR: %s: file: %s line: %d dungeon: %u failed to: sort +4nr -o %s %s exit code: %d\n",
* __func__, __FILE__, __LINE__, dnum, newfil, delfil, ret);
* not_reached ();
* }
*/
int
fork_exec (char *file, char *arglist[])
{
pid_t pid; /* fork(2) return */
pid_t wait_ret; /* waitpid(2) return */
int stat_loc; /* status of the dead child process */
int ret = 0; /* execvp(3) or child exit return code */
/*
* fork a child process
*/
pid = fork ();
if (pid < 0) {
quit (1, "ERROR: %s: file: %s line: %d dungeon: %u filed to fork: %s\n",
__func__, __FILE__, __LINE__, dnum, strerror (errno));
not_reached ();
}
/*
* child process - exec the command
*/
if (pid == 0) {
ret = execvp (file, arglist);
if (ret < 0) {
quit (1, "ERROR: %s: file: %s line: %d dungeon: %u failed to execvp: %s error: %s\n",
__func__, __FILE__, __LINE__, dnum, file, strerror (errno));
not_reached ();
}
quit (1, "ERROR: %s: file: %s line: %d dungeon: %u child execvp returned with: %jd: error: %s\n",
__func__, __FILE__, __LINE__, dnum, (intmax_t) pid, strerror (errno));
not_reached ();
/*
* parent process - monitor child process
*/
} else {
wait_ret = waitpid (pid, &stat_loc, 0);
if (wait_ret < 0) {
quit (1, "ERROR: %s: file: %s line: %d dungeon: %u failed to waitpid(%jd, &stat_loc, 0): %s\n",
__func__, __FILE__, __LINE__, dnum, (intmax_t) pid, strerror (errno));
not_reached ();
}
ret = WEXITSTATUS(stat_loc);
}
/*
* return child exit code
*/
return ret;
}