int forkexecve(const char* cmd, int *kq, struct kevent *ke, Service* svc, int aux) { char* data =strdup(cmd); char **argv =NULL; char * p = strtok ((char*)data, " "); int n_spaces = 0, i; while (p) { argv = realloc (argv, sizeof (char*) * ++n_spaces); if (argv == NULL) exit (-1); /* memory allocation failed */ argv[n_spaces-1] = p; p = strtok (NULL, " "); } /* realloc one extra element for the last NULL */ argv = realloc (argv, sizeof (char*) * (n_spaces+1)); argv[n_spaces] = 0; /* print the result */ for (i = 0; i < (n_spaces+1); ++i) dbg ("argv[%d] = %s\n", i, argv[i]); int pid = fork(); if ( pid == 0 ) { execvp(argv[0], argv); } else if (!(pid > 0)) { dbg("fork failed\n"); pid =0; goto clean; } if(!aux) PIDList_addpid(&svc->PL, pid); else PIDList_addpid(&svc->AuxPL, pid); /* watch for forks and exits */ attach_pid_to_kqueue(kq, ke, pid); /* free it */ clean: free (argv); free (data); return pid; }
void process_proc_kevents(int *kq, struct kevent *ke, Service *svc) { if (ke->fflags & NOTE_FORK) dbg("pid %lu called fork()\n", ke->ident); if (ke->fflags & NOTE_CHILD) { dbg("we have a child: %lu\n", ke->ident); attach_pid_to_kqueue(kq, ke, ke->ident); PIDList_addpid(&svc->PL, ke->ident); } if (ke->fflags & NOTE_EXIT) { dbg("pid %lu exited\n", ke->ident); detach_pid_from_kqueue(kq, ke, ke->ident); PIDList_delpid(&svc->PL, ke->ident); PIDList_delpid(&svc->AuxPL, ke->ident); /* one of these contains it */ reap(); if (ke->ident == svc->MainPID) { dbg("Main PID has exited.\n"); svc->MainPIDExited =1; } else if (ke->ident == svc->AuxMainPID) { dbg("Main AUX PID has exited.\n"); svc->AuxMainPIDExited =1; } } if (ke->fflags & NOTE_TRACKERR) printf("couldnt attach to child of %lu\n", ke->ident); }