Functions | |
int | di_exec_full (const char *path, const char *const argv[], di_io_handler *stdout_handler, di_io_handler *stderr_handler, void *io_user_data, di_process_handler *parent_prepare_handler, void *parent_prepare_user_data, di_process_handler *child_prepare_handler, void *child_prepare_user_data) |
int | di_exec (const char *path, const char *const argv[]) |
int | di_exec_shell_full (const char *const cmd, di_io_handler *stdout_handler, di_io_handler *stderr_handler, void *io_user_data, di_process_handler *parent_prepare_handler, void *parent_prepare_user_data, di_process_handler *child_prepare_handler, void *child_prepare_user_data) |
int | di_exec_shell (const char *const cmd) |
int | di_exec_shell_log (const char *const cmd) |
int | di_exec_mangle_status (int status) |
int | di_execlog (const char *const cmd) __attribute__((deprecated)) |
Variables | |
di_io_handler | di_exec_io_log |
di_process_handler | di_exec_prepare_chdir |
di_process_handler | di_exec_prepare_chroot |
|
execv like call
00082 { 00083 return di_exec_full (path, argv, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 00084 } |
|
execv like call
00042 { 00043 char line[MAXLINE]; 00044 pid_t pid; 00045 int fds[4] = { -1, }, mode = 0, pipes = 0, i; 00046 00047 if (stdout_handler) 00048 { 00049 mode += 1; 00050 pipes++; 00051 } 00052 if (stderr_handler) 00053 { 00054 mode += 2; 00055 pipes++; 00056 } 00057 00058 for (i = 0; i < pipes; i++) 00059 pipe (&fds[i * 2]); 00060 00061 pid = fork (); 00062 00063 if (pid <= 0) 00064 { 00065 for (i = 0; i < pipes; i++) 00066 close (fds[i * 2]); 00067 } 00068 00069 if (pid == 0) 00070 { 00071 int temp, realfds[3] = 00072 { 00073 0, 00074 fds[1], 00075 fds[3] 00076 }; 00077 00078 temp = open ("/dev/null", O_RDWR); 00079 00080 switch (mode) 00081 { 00082 case 0: 00083 realfds[1] = temp; 00084 realfds[2] = temp; 00085 break; 00086 case 2: 00087 realfds[1] = temp; 00088 realfds[2] = fds[1]; 00089 break; 00090 case 1: 00091 realfds[2] = fds[1]; 00092 break; 00093 } 00094 00095 for (i = 1; i <= 2; i++) 00096 dup2 (realfds[i], i); 00097 00098 close (temp); 00099 } 00100 00101 for (i = 0; i < pipes; i++) 00102 close (fds[i * 2 + 1]); 00103 00104 if (pid == 0) 00105 { 00106 if (child_prepare_handler) 00107 if (child_prepare_handler (pid, child_prepare_user_data)) 00108 exit (255); 00109 00110 execv (path, (char *const *) argv); 00111 exit (127); 00112 } 00113 else if (pid < 0) 00114 { 00115 di_log (DI_LOG_LEVEL_WARNING, "fork failed"); 00116 return -1; 00117 } 00118 else 00119 { 00120 int status = -1; 00121 struct pollfd pollfds[pipes]; 00122 struct files 00123 { 00124 FILE *file; 00125 di_io_handler *handler; 00126 } 00127 files[pipes]; 00128 00129 for (i = 0; i < pipes; i++) 00130 { 00131 fcntl (fds[i * 2], F_SETFL, O_NONBLOCK); 00132 files[i].file = fdopen (fds[i * 2], "r"); 00133 pollfds[i].fd = fds[i * 2]; 00134 pollfds[i].events = POLLIN; 00135 } 00136 00137 switch (mode) 00138 { 00139 case 2: 00140 files[0].handler = stderr_handler; 00141 break; 00142 case 3: 00143 files[1].handler = stderr_handler; 00144 case 1: 00145 files[0].handler = stdout_handler; 00146 break; 00147 } 00148 00149 if (parent_prepare_handler && parent_prepare_handler (pid, parent_prepare_user_data)) 00150 kill (pid, 9); 00151 else if (pipes) 00152 while (poll (pollfds, pipes, -1) >= 0) 00153 { 00154 bool exit = false; 00155 00156 for (i = 0; i < pipes; i++) 00157 { 00158 if (pollfds[i].revents & POLLIN) 00159 { 00160 while (fgets (line, sizeof (line), files[i].file) != NULL) 00161 { 00162 size_t len = strlen (line); 00163 if (line[len - 1] == '\n') 00164 { 00165 line[len - 1] = '\0'; 00166 len--; 00167 } 00168 files[i].handler (line, len, io_user_data); 00169 } 00170 exit = true; 00171 } 00172 } 00173 00174 if (exit) 00175 continue; 00176 00177 for (i = 0; i < pipes; i++) 00178 if (pollfds[i].revents & POLLHUP) 00179 exit = true; 00180 00181 if (exit) 00182 break; 00183 } 00184 00185 if (!waitpid (pid, &status, 0)) 00186 return -1; 00187 00188 for (i = 0; i < pipes; i++) 00189 fclose (files[i].file); /* closes fds[i * 2] */ 00190 00191 return status; 00192 } 00193 00194 return -1; 00195 } |
|
mangle status like sh does it: * if signaled: 128 + signal * else return code
00228 { 00229 if (WIFEXITED (status)) 00230 return WEXITSTATUS (status); 00231 if (WIFSIGNALED (status)) 00232 return 128 + WTERMSIG (status); 00233 if (WIFSTOPPED (status)) 00234 return 128 + WSTOPSIG (status); 00235 return status; 00236 } |
|
system like call
00110 { 00111 return di_exec_shell_full (cmd, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 00112 } |
|
system like call
00198 { 00199 const char *const argv[] = { "sh", "-c", cmd, NULL }; 00200 return di_exec_full ("/bin/sh", argv, stdout_handler, stderr_handler, io_user_data, parent_prepare_handler, parent_prepare_user_data, child_prepare_handler, child_prepare_user_data); 00201 } |
|
system like call with output via log
00122 { 00123 return di_exec_shell_full (cmd, di_exec_io_log, NULL, NULL, NULL, NULL, NULL, NULL); 00124 } |
|
00139 { 00140 return di_exec_shell_log (cmd); 00141 } |
|
logs the output |
|
chdir to user_data
|
|
chroot to user_data
|