struct samba_runcmd_state {
int stdout_log_level;
int stderr_log_level;
- struct tevent_fd *fde_stdin;
struct tevent_fd *fde_stdout;
struct tevent_fd *fde_stderr;
int fd_stdin, fd_stdout, fd_stderr;
waitpid(state->pid, NULL, 0);
state->pid = -1;
}
+
+ if (state->fd_stdin != -1) {
+ close(state->fd_stdin);
+ }
return 0;
}
char **argv;
va_list ap;
+ if (argv0 == NULL) {
+ return NULL;
+ }
+
req = tevent_req_create(mem_ctx, &state,
struct samba_runcmd_state);
if (req == NULL) {
state->stdout_log_level = stdout_log_level;
state->stderr_log_level = stderr_log_level;
+ state->fd_stdin = -1;
state->arg0 = talloc_strdup(state, argv0[0]);
if (tevent_req_nomem(state->arg0, req)) {
set_blocking(state->fd_stderr, false);
set_blocking(state->fd_stdin, false);
+ smb_set_close_on_exec(state->fd_stdin);
+ smb_set_close_on_exec(state->fd_stdout);
+ smb_set_close_on_exec(state->fd_stderr);
+
talloc_set_destructor(state, samba_runcmd_state_destructor);
state->fde_stdout = tevent_add_fd(ev, state,
if (tevent_req_nomem(state->fde_stdout, req)) {
close(state->fd_stdout);
close(state->fd_stderr);
- close(state->fd_stdin);
return tevent_req_post(req, ev);
}
tevent_fd_set_auto_close(state->fde_stdout);
req);
if (tevent_req_nomem(state->fde_stdout, req)) {
close(state->fd_stderr);
- close(state->fd_stdin);
return tevent_req_post(req, ev);
}
tevent_fd_set_auto_close(state->fde_stderr);
- state->fde_stdin = tevent_add_fd(ev, state,
- state->fd_stdin,
- 0,
- samba_runcmd_io_handler,
- req);
- if (tevent_req_nomem(state->fde_stdin, req)) {
- close(state->fd_stdin);
- return tevent_req_post(req, ev);
- }
- tevent_fd_set_auto_close(state->fde_stdin);
-
if (!timeval_is_zero(&endtime)) {
tevent_req_set_endtime(req, ev, endtime);
}
dup2(p1[1], 1);
dup2(p2[1], 2);
+ close(p1[1]);
+ close(p2[1]);
+ close(p3[0]);
+
argv = str_list_copy(state, discard_const_p(const char *, argv0));
if (!argv) {
fprintf(stderr, "Out of memory in child\n");
va_start(ap, argv0);
while (1) {
+ const char **l;
char *arg = va_arg(ap, char *);
if (arg == NULL) break;
- argv = discard_const_p(char *, str_list_add((const char **)argv, arg));
- if (!argv) {
+ l = discard_const_p(const char *, argv);
+ l = str_list_add(l, arg);
+ if (l == NULL) {
fprintf(stderr, "Out of memory in child\n");
_exit(255);
}
+ argv = discard_const_p(char *, l);
}
va_end(ap);
} else if (fde == state->fde_stderr) {
level = state->stderr_log_level;
fd = state->fd_stderr;
- } else if (fde == state->fde_stdin) {
- char c;
- if (read(state->fd_stdin, &c, 1) != 1) {
- /* the child has closed its stdin */
- talloc_free(fde);
- state->fde_stdin = NULL;
- return;
- }
} else {
return;
}
SIGCHLD in the standard
process model.
*/
- tevent_req_done(req);
+ DEBUG(0, ("Error in waitpid() unexpectedly got ECHILD "
+ "for %s child %d - %s, "
+ "someone has set SIGCHLD to SIG_IGN!\n",
+ state->arg0, (int)state->pid, strerror(errno)));
+ tevent_req_error(req, errno);
return;
}
DEBUG(0,("Error in waitpid() for child %s - %s \n",