/* Build arguments for running program. */
tprog = get_pool_memory(PM_FNAME);
pm_strcpy(&tprog, prog);
- build_argc_argv(tprog, &bargc, bargv, MAX_ARGV);
+ build_argc_argv(mp_chr(tprog), &bargc, bargv, MAX_ARGV);
#ifdef xxxxxx
printf("argc=%d\n", bargc);
int i;
}
/* Start worker process */
switch (bpipe->worker_pid = fork()) {
- case -1:
+ case -1: /* error */
free(bpipe);
return NULL;
dup2(readp[1], 1); /* dup our read to his stdout */
dup2(readp[1], 2); /* and his stderr */
}
+ for (int i=3; i<=32; i++) { /* close any open file descriptors */
+ close(i);
+ }
execvp(bargv[0], bargv); /* call the program */
exit(errno); /* shouldn't get here */
/* wait for worker child to exit */
for ( ;; ) {
- wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
- if (wpid == bpipe->worker_pid || (wpid == -1 && errno != EINTR)) {
+ Dmsg2(200, "Wait for %d opt=%d\n", bpipe->worker_pid, wait_option);
+ do {
+ wpid = waitpid(bpipe->worker_pid, &chldstatus, wait_option);
+ } while (wpid == -1 && (errno == EINTR || errno == EAGAIN));
+ if (wpid == bpipe->worker_pid || wpid == -1) {
+ Dmsg3(200, "Got break wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
+ wpid==-1?strerror(errno):"none");
break;
}
+ Dmsg3(200, "Got wpid=%d status=%d ERR=%s\n", wpid, chldstatus,
+ wpid==-1?strerror(errno):"none");
if (remaining_wait > 0) {
- sleep(1); /* wait one second */
+ bmicrosleep(1, 0); /* wait one second */
remaining_wait--;
} else {
- stat = ETIME; /* set timeout, if no other status */
+ stat = 1; /* set error status */
+ errno = ETIME; /* set timed out */
wpid = -1;
break; /* don't wait any longer */
}
}
- if (wpid != -1 && WIFEXITED(chldstatus)) {
- stat = WEXITSTATUS(chldstatus);
+ if (wpid > 0) {
+ if (WIFEXITED(chldstatus)) { /* process exit()ed */
+ stat = WEXITSTATUS(chldstatus);
+ Dmsg1(200, "status =%d\n", stat);
+ } else if (WIFSIGNALED(chldstatus)) { /* process died */
+ stat = 1;
+ Dmsg0(200, "Signaled\n");
+ }
if (stat != 0) {
- errno = ECHILD;
+ errno = ECHILD; /* set child errno */
}
- }
+ }
if (bpipe->timer_id) {
stop_child_timer(bpipe->timer_id);
}
free(bpipe);
-#ifdef HAVE_FREEBSD_OS
- stat = 0; /* kludge because FreeBSD doesn't seem to return valid status */
-#endif
+ Dmsg1(200, "returning stat = %d\n", stat);
return stat;
}
* Run an external program. Optionally wait a specified number
* of seconds. Program killed if wait exceeded. Optionally
* return the output from the program (normally a single line).
+ *
+ * Contrary to my normal calling conventions, this program
+ *
+ * Returns: 0 on success
+ * non-zero on error
*/
int run_program(char *prog, int wait, POOLMEM *results)
{
return 0;
}
if (results) {
- results[0] = 0;
- stat1 = fgets(results, sizeof_pool_memory(results), bpipe->rfd) != NULL;
+ mp_chr(results)[0] = 0;
+ stat1 = fgets(mp_chr(results), sizeof_pool_memory(results), bpipe->rfd) == NULL;
} else {
- stat1 = 1;
+ stat1 = 0;
}
stat2 = close_bpipe(bpipe);
- return stat1 && stat2;
+ return stat2 != 0 ? stat2 : stat1;
}