void destroy_state(struct state *s) { unsigned int i; if(s == NULL){ return; } if(s->s_up){ destroy_katcl(s->s_up, 0); s->s_up = NULL; } if(s->s_vector){ for(i = 0; i < s->s_count; i++){ destroy_child(s->s_vector[i]); s->s_vector[i] = NULL; } free(s->s_vector); s->s_vector = NULL; } s->s_count = 0; s->s_finished = 0; s->s_code = 0; free(s); }
int main(int argc, char *argv[]) { vertex v; command com; v.left.in = -1; v.right.in = -1; vertex_init(&v, 0); sscanf(argv[1], "%d", &v.value); while(checked_read(0, &com, sizeof(com))) { switch(com.code) { case COM_ADD: add(&v, com); break; case COM_FIND: find(&v, com); break; case COM_WALK: walk(&v); break; case COM_STOP: if(v.left.in != -1) destroy_child(&v.left); if(v.right.in != -1) destroy_child(&v.right); close(0); close(1); exit(0); break; default: fatal("code unknown"); break; } } return 0; }
int launch_child(struct state *s, char **vector) { int fds[2], fd; pid_t pid; struct child **tmp; struct child *c; struct katcl_line *k; unsigned int i; tmp = realloc(s->s_vector, sizeof(struct child *) * (s->s_count + 1)); if(tmp == NULL){ return -1; } s->s_vector = tmp; c = malloc(sizeof(struct child)); if(c == NULL){ return -1; } c->c_pid = 0; c->c_line = NULL; c->c_status = 0; if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0){ sync_message_katcl(s->s_up, KATCP_LEVEL_ERROR, KCPCON_NAME, "unable to allocate socketpair: %s", strerror(errno)); destroy_child(c); return -1; } pid = fork(); if(pid < 0){ sync_message_katcl(s->s_up, KATCP_LEVEL_ERROR, KCPCON_NAME, "unable to fork: %s", strerror(errno)); close(fds[0]); close(fds[1]); destroy_child(c); return -1; } if(pid > 0){ c->c_pid = pid; close(fds[0]); fcntl(fds[1], F_SETFD, FD_CLOEXEC); c->c_line = create_katcl(fds[1]); if(c->c_line == NULL){ destroy_child(c); } s->s_vector[s->s_count] = c; s->s_count++; return 0; } /* WARNING: can not return from code below, have to exit() */ close(fds[1]); fd = fds[0]; k = create_katcl(fd); for(i = STDIN_FILENO; i <= STDERR_FILENO; i++){ if(fd != i){ if(dup2(fd, i) < 0){ if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCON_NAME, "unable to duplicate fd %d to replace %d: %s", fd, i, strerror(errno)); } exit(1); } } } execvp(vector[0], vector); if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCON_NAME, "unable to run %s: %s", vector[0], strerror(errno)); } exit(1); return -1; }