int main(int argc, char **argv) { err_setarg0(argv[0]); assert(argc == 1); pthread_t thread[MAX_THREADS]; for (int i = 0; i < MAX_THREADS; i++) { int rc = pthread_create(&thread[i], 0, thread_function, (void *)(uintptr_t)i); if (rc != 0) { errno = rc; err_syserr("failed to create thread %d", i); } } for (int i = 0; i < MAX_THREADS; i++) { void *vp; int rc = pthread_join(thread[i], &vp); if (rc != 0) { errno = rc; err_syserr("Failed to join TID %d", i); } printf("TID %d returned %p\n", i, vp); } return 0; }
/* Helper function that spawns processes */ static int spawn_proc(int in, int out, struct command *cmd) { pid_t pid; if ((pid = fork()) == 0) { if (in != 0) { if (dup2(in, 0) < 0) err_syserr("dup2() failed on stdin for %s: ", cmd->argv[0]); ; close(in); } if (out != 1) { if (dup2(out, 1) < 0) err_syserr("dup2() failed on stdout for %s: ", cmd->argv[0]); close(out); } fprintf(stderr, "%d: executing %s\n", (int)getpid(), cmd->argv[0]); execvp(cmd->argv[0], cmd->argv); err_syserr("failed to execute %s: ", cmd->argv[0]); } else if (pid < 0) { err_syserr("fork failed: "); } return pid; }
static void test_ops(void) { Set *s1 = set_create(); Set *s2 = set_create(); Set *s3 = set_create(); if (s1 == 0 || s2 == 0 || s3 == 0) err_syserr("Out of memory\n"); load_set(s1, 1, 3, 4, 6); dump_set("S1", s1); load_set(s2, 2, 5, 7, 9); dump_set("S2", s2); set_union(s1, s2, s3); dump_set("S1 union S2", s3); set_empty(s3); set_intersect(s1, s2, s3); dump_set("S1 intersect S2", s3); set_empty(s3); set_difference(s1, s2, s3); dump_set("S1 minus S2", s3); set_empty(s3); set_difference(s2, s1, s3); dump_set("S2 minus S1", s3); set_destroy(s1); set_destroy(s2); set_destroy(s3); }
static void stack_push_str(Stack *stack, const char *str) { if (stack->tos == stack->size) { size_t n_size = (stack->size + 2) * 2; void *n_data = realloc(stack->stack, n_size * sizeof(*stack->stack)); if (n_data == 0) err_syserr("out of memory\n"); stack->size = n_size; stack->stack = n_data; } stack->stack[stack->tos] = strdup(str); if (stack->stack[stack->tos] == 0) err_syserr("out of memory\n"); stack->tos++; }
static void test_set(void) { Set *set = set_create(); if (set == 0) err_syserr("Out of memory\n"); load_set(set, 1, 3, 4, 6); dump_set("S0", set); set_destroy(set); }
/* Helper function that forks pipes */ static void fork_pipes(int n, struct command *cmd) { int i; int in = 0; int fd[2]; for (i = 0; i < n - 1; ++i) { pipe(fd); spawn_proc(in, fd[1], cmd + i); close(fd[1]); in = fd[0]; } if (dup2(in, 0) < 0) { err_syserr("dup2() failed on stdin for %s: ", cmd[i].argv[0]); } fprintf(stderr, "%d: executing %s\n", (int)getpid(), cmd[i].argv[0]); execvp(cmd[i].argv[0], cmd[i].argv); err_syserr("failed to execute %s: ", cmd[i].argv[0]); }
int main(int argc, char **argv) { int pid, fds[2], pid1; char buf[200]; err_setarg0(argv[0]); err_setlogopts(ERR_PID|ERR_MICRO); dump_pgrps(); if (pipe(fds) != 0) err_syserr("failed to create pipe: "); pid = fork(); if (pid == 0) { close(fds[0]); for (int i = 0; i < 3; i++) { printf("Prompt %d: ", i); fflush(0); if (scanf("%199s", buf) != 1) { int errnum = errno; err_remark("Child1:\n"); dump_pgrps(); errno = errnum; err_sysrem("scanf() failed: "); clearerr(stdin); } else { /* Write the null terminator too */ ssize_t rbytes = strlen(buf) + 1; ssize_t wbytes = write(fds[1], buf, rbytes); if (wbytes != rbytes) err_sysrem("short write (read %zu, write %zu)\n", rbytes, wbytes); } sleep(3); } } else { pid1 = fork(); if (pid1 == 0) { close(fds[1]); for (int i = 0; i < 3; i++) { if (read(fds[0], buf, sizeof(buf)) > 0) printf("Input %d: %s\n", i, buf); else { int errnum = errno; err_remark("Child2:\n"); dump_pgrps(); errno = errnum; err_sysrem("read() failed: "); } } } else if (argc > 2) { err_remark("Kids are %d and %d\n", pid, pid1); sleep(5); err_remark("Parent exits\n"); } else if (argc > 1 && argv != 0) // Avoid compilation warning for unused argv { err_remark("Kids are %d and %d\n", pid, pid1); int status; int corpse = wait(&status); err_remark("Parent gets PID %d status 0x%.4X\n", corpse, status); } } return 0; }