int test__attr(int subtest __maybe_unused) { struct stat st; char path_perf[PATH_MAX]; char path_dir[PATH_MAX]; /* First try developement tree tests. */ if (!lstat("./tests", &st)) return run_dir("./tests", "./perf"); /* Then installed path. */ snprintf(path_dir, PATH_MAX, "%s/tests", get_argv_exec_path()); snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR); if (!lstat(path_dir, &st) && !lstat(path_perf, &st)) return run_dir(path_dir, path_perf); return TEST_SKIP; }
void cmd_handler(int cmd, char *arg) { if (cmd < 6) /* handles first lot of commands as they all can be implemented by forking a child process easily */ { pid_t pid = fork(); if (pid > CHILD_PID) /* parent process wait for child to finish before exiting function and going back to prompt */ { wait(&pid); } else if (pid == CHILD_PID) /* forked child process runs entered command */ { switch (cmd) { case 0: run_clr(); break; case 1: run_dir(arg); break; case 2: run_echo(arg); break; case 3: run_environ(); break; case 4: run_help(); break; case 5: run_pause(); break; default: printf("Congratulations! You've broken my code."); /* I really don't think it's possible to get here... */ } } else { fprintf(stderr, "Failed to fork process. Fatal error, exiting program.\n"); exit(1); } } else /* handles last commands: because of the way I've implemented the execution of the shell, it would be very inconvenient to handle them in a child process (without using shared memory) */ { switch (cmd) { case 6: run_quit(); break; case 7: run_cd(arg); break; default: printf("Again! You did it again!"); /* again, not really possible */ } } }
int test__attr(void) { struct stat st; char path_perf[PATH_MAX]; char path_dir[PATH_MAX]; /* First try developement tree tests. */ if (!lstat("./tests", &st)) return run_dir("./tests", "./perf"); /* Then installed path. */ snprintf(path_dir, PATH_MAX, "%s/tests", perf_exec_path()); snprintf(path_perf, PATH_MAX, "%s/perf", BINDIR); if (!lstat(path_dir, &st) && !lstat(path_perf, &st)) return run_dir(path_dir, path_perf); fprintf(stderr, " (omitted)"); return 0; }
static void mms_queue_run(char *dir, int (*deliver)(MmsEnvelope *), double sleepsecs, int num_threads, int *rstop) { int i, qstop = 0; List *stack = gwlist_create(); // static struct Qthread_t *tlist; struct Qthread_t *tlist; debug("", 0, "mms_queue_run: %s", dir); max_live_exceeded_warning_issued = 0; number_of_threads = num_threads; gw_assert(num_threads>0); if (tlists == NULL) tlists = dict_create(10, NULL); Octstr *odir = octstr_create(dir); tlist = gw_malloc(num_threads*sizeof tlist[0]); dict_put(tlists, odir, tlist); gw_assert(tlist == dict_get(tlists,odir)); debug("",0,"tlist allocated at addr %p", &tlist[0]); octstr_destroy(odir); for (i = 0; i<num_threads; i++) { /* Create threads for sending. */ debug("",0,"%s tlist[%d] has addr: %p", dir, i, &tlist[i]); tlist[i].l = gwlist_create(); gwlist_add_producer(tlist[i].l); tlist[i].deliver = deliver; gwthread_create((gwthread_func_t *)tdeliver, &tlist[i]); } i = 0; /* For stepping through above array. */ do { Octstr *xdir = NULL; gwlist_append(stack, octstr_create("")); /* Put initial dir on there. */ while (!*rstop && (xdir = gwlist_extract_first(stack)) != NULL) { int ret = run_dir(dir, octstr_get_cstr(xdir), tlist, num_threads, &i, stack); octstr_destroy(xdir); xdir = NULL; if (ret < 0) { if (ret <= -2) qstop = 1; goto qloop; } } octstr_destroy(xdir); if (*rstop) break; qloop: gwthread_sleep(sleepsecs); } while (!qstop); /* We are out of the queue, time to go away. */ for (i = 0; i<num_threads; i++) if (tlist[i].l) gwlist_remove_producer(tlist[i].l); gwthread_join_every((gwthread_func_t *)tdeliver); /* Wait for them all to terminate. */ for (i = 0; i<num_threads; i++) if (tlist[i].l) gwlist_destroy(tlist[i].l,NULL); /* Final destroy if needed. */ gw_free(tlist); gwlist_destroy(stack, (gwlist_item_destructor_t *)octstr_destroy); return; }