static FILE *open_logfile(const char *logfilename) { FILE *file; unlink(logfilename); file = fopen(logfilename, "w"); if (!file) outputerr("## couldn't open logfile %s\n", logfilename); return file; }
static void disable_coredumps(void) { struct rlimit limit = { .rlim_cur = 0, .rlim_max = 0 }; if (debug == TRUE) { (void)signal(SIGABRT, SIG_DFL); (void)signal(SIGSEGV, SIG_DFL); return; } if (setrlimit(RLIMIT_CORE, &limit) != 0) perror( "setrlimit(RLIMIT_CORE)" ); prctl(PR_SET_DUMPABLE, FALSE); } static void enable_coredumps(void) { struct rlimit limit = { .rlim_cur = RLIM_INFINITY, .rlim_max = RLIM_INFINITY }; if (debug == TRUE) return; prctl(PR_SET_DUMPABLE, TRUE); (void) setrlimit(RLIMIT_CORE, &limit); } static void set_make_it_fail(void) { int fd; const char *buf = "1"; /* If we failed last time, don't bother trying in future. */ if (shm->do_make_it_fail == TRUE) return; fd = open("/proc/self/make-it-fail", O_WRONLY); if (fd == -1) return; if (write(fd, buf, 1) == -1) { if (errno != EPERM) outputerr("writing to /proc/self/make-it-fail failed! (%s)\n", strerror(errno)); else shm->do_make_it_fail = TRUE; } close(fd); }
extern void CommandExportMatchText(char *sz) { FILE *pf; listOLD *pl; int nGames; char *szCurrent; int i; sz = NextToken(&sz); if (!sz || !*sz) { outputl(_("You must specify a file to export to (see `help export " "match text').")); return; } /* Find number of games in match */ for (pl = lMatch.plNext, nGames = 0; pl != &lMatch; pl = pl->plNext, nGames++); for (pl = lMatch.plNext, i = 0; pl != &lMatch; pl = pl->plNext, i++) { szCurrent = filename_from_iGame(sz, i); if (!i) { if (!confirmOverwrite(sz, fConfirmSave)) return; setDefaultFileName(sz); } if (!strcmp(szCurrent, "-")) pf = stdout; else if ((pf = g_fopen(szCurrent, "w")) == 0) { outputerr(szCurrent); return; } ExportGameText(pf, pl->p, i, i == nGames - 1); if (pf != stdout) fclose(pf); } }
/* * Set a new seed in the parent. * Called when a new child starts, so we don't repeat runs across different pids. * We only reseed in the main pid, all the children are expected to periodically * check if the seed changed, and reseed accordingly. * * Caveat: Not used if we passed in our own seed with -s */ void reseed(void) { if (getpid() != mainpid) { outputerr("Reseeding should only happen from parent!\n"); exit(EXIT_FAILURE); } /* don't change the seed if we passed -s */ if (user_set_seed == TRUE) return; /* We are reseeding. */ shm->seed = new_seed(); }
static void toggle_taint_flag_by_name(char *beg, char *end) { char flagname[TAINT_NAME_LEN]; char *name; if (end == NULL) { name = beg; } else { int maxlen; name = flagname; maxlen = end - beg; if (maxlen > (TAINT_NAME_LEN - 1)) maxlen = TAINT_NAME_LEN - 1; strncpy(flagname, beg, maxlen); flagname[maxlen] = 0; } if (strcmp(name,"PROPRIETARY_MODULE") == 0) toggle_taint_flag(TAINT_PROPRIETARY_MODULE); else if (strcmp(name,"FORCED_MODULE") == 0) toggle_taint_flag(TAINT_FORCED_MODULE); else if (strcmp(name,"UNSAFE_SMP") == 0) toggle_taint_flag(TAINT_UNSAFE_SMP); else if (strcmp(name,"FORCED_RMMOD") == 0) toggle_taint_flag(TAINT_FORCED_RMMOD); else if (strcmp(name,"MACHINE_CHECK") == 0) toggle_taint_flag(TAINT_MACHINE_CHECK); else if (strcmp(name,"BAD_PAGE") == 0) toggle_taint_flag(TAINT_BAD_PAGE); else if (strcmp(name,"USER") == 0) toggle_taint_flag(TAINT_USER); else if (strcmp(name,"DIE") == 0) toggle_taint_flag(TAINT_DIE); else if (strcmp(name,"OVERRIDDEN_ACPI_TABLE") == 0) toggle_taint_flag(TAINT_OVERRIDDEN_ACPI_TABLE); else if (strcmp(name,"WARN") == 0) toggle_taint_flag(TAINT_WARN); else if (strcmp(name,"CRAP") == 0) toggle_taint_flag(TAINT_CRAP); else if (strcmp(name,"FIRMWARE_WORKAROUND") == 0) toggle_taint_flag(TAINT_FIRMWARE_WORKAROUND); else if (strcmp(name,"OOT_MODULE") == 0) toggle_taint_flag(TAINT_OOT_MODULE); else { outputerr("Unrecognizable kernel taint flag \"%s\".\n", name); exit(EXIT_FAILURE); } }
static FILE * find_logfile_handle(void) { pid_t pid; int i; pid = getpid(); if (pid == initpid) return mainlogfile; if (pid == shm->mainpid) return mainlogfile; if (pid == watchdog_pid) return mainlogfile; i = find_childno(pid); if (i != CHILD_NOT_FOUND) return shm->children[i]->logfile; else { /* try one more time. FIXME: This is awful. */ unsigned int j; sleep(1); i = find_childno(pid); if (i != CHILD_NOT_FOUND) return shm->children[i]->logfile; outputerr("## Couldn't find logfile for pid %d\n", pid); dump_childnos(); outputerr("## Logfiles for pids: "); for_each_child(j) outputerr("%p ", shm->children[j]->logfile); outputerr("\n"); } return NULL; }
static void reenable_coredumps(void) { if (debug == TRUE) return; prctl(PR_SET_DUMPABLE, TRUE); if (setrlimit(RLIMIT_CORE, &oldrlimit) != 0) { outputerr("[%d] Error restoring rlimits to cur:%d max:%d (%s)\n", getpid(), (unsigned int) oldrlimit.rlim_cur, (unsigned int) oldrlimit.rlim_max, strerror(errno)); } }
void register_ioctl_group(const struct ioctl_group *grp) { /* group could be empty e.g. if everything is ifdeffed out */ if (grp->ioctls_cnt == 0) return; if (grps_cnt == ARRAY_SIZE(grps)) { outputerr("WARNING: please grow IOCTL_GROUPS_MAX.\n"); return; } grps[grps_cnt] = grp; ++grps_cnt; }
double perceptron::train(std::vector<double> &input, std::vector<double> &target) { double totalErr = 0; test(input); for (int x = 0; x < outputs; x++) { double err = outputerr(output,target,x); totalErr+=err*err; for (int y = 0; y < inputs; y++) { weight[x][y] -= rate*err*input[y]; } weight[x][inputs] -= rate*err*(1); // bias } return totalErr; }
double perceptron::train(std::vector<unsigned int> &input, std::vector<double> &target) { double totalErr = 0; test(input); for (int x = 0; x < outputs; x++) { double err = outputerr(output,target,x); totalErr+=err*err; double rateTimesError = rate*err; for (unsigned int y = 0; y < input.size(); y++) { weight[x][input[y]] -= rateTimesError; } weight[x][inputs] -= rateTimesError; // bias } return totalErr; }
static FILE *robust_find_logfile_handle(void) { unsigned int j; FILE *handle = NULL; if ((logging == TRUE) && (logfiles_opened)) { handle = find_logfile_handle(); if (!handle) { outputerr("## child logfile handle was null logging to main!\n"); (void)fflush(stdout); for_each_pidslot(j) shm->logfiles[j] = mainlogfile; sleep(5); handle = find_logfile_handle(); } } return handle; }
void init_uids(void) { struct passwd *passwd; orig_uid = getuid(); orig_gid = getgid(); if (dropprivs == FALSE) return; passwd = getpwnam("nobody"); if (passwd == NULL) { outputerr("Error getting nobody pwent (%s)\n", strerror(errno)); exit(EXIT_FAILURE); } nobody_uid = passwd->pw_uid; nobody_gid = passwd->pw_gid; }
static void dump_syscall_records(void) { FILE *fd; unsigned int i; fd = fopen("trinity-post-mortem.log", "w"); if (!fd) { outputerr("Failed to write post mortem log (%s)\n", strerror(errno)); return; } for_each_child(i) { dump_syscall_rec(fd, &shm->children[i]->syscall); fprintf(fd, "\n"); } fclose(fd); }
static void setup_shm_postargs(void) { if (user_set_seed == TRUE) { shm->seed = init_seed(seed); /* Set seed in parent thread */ set_seed(0); } if (user_specified_children != 0) shm->max_children = user_specified_children; else shm->max_children = sysconf(_SC_NPROCESSORS_ONLN); if (shm->max_children > MAX_NR_CHILDREN) { outputerr("Increase MAX_NR_CHILDREN!\n"); exit(EXIT_FAILURE); } }
void pids_init(void) { unsigned int i; if (read_pid_max()) { #ifdef __x86_64__ pidmax = 4194304; #else pidmax = 32768; #endif outputerr("Couldn't read pid_max from proc\n"); } output(0, "Using pid_max = %d\n", pidmax); pids = alloc_shared(max_children * sizeof(int)); for_each_child(i) pids[i] = EMPTY_PIDSLOT; }
void toggle_syscall_n(int calln, bool state, const char *arg, const char *arg_name) { if (calln == -1) { outputerr("No idea what syscall (%s) is.\n", arg); exit(EXIT_FAILURE); } validate_specific_syscall(syscalls, calln); if (state == TRUE) { syscalls[calln].entry->flags |= ACTIVE; activate_syscall(calln); } else { syscalls[calln].entry->flags |= TO_BE_DEACTIVATED; } output(0, "Marking syscall %s (%d) as to be %sabled.\n", arg_name, calln, state ? "en" : "dis"); }
static void set_make_it_fail(void) { int fd; const char *buf = "1"; /* If we failed last time, don't bother trying in future. */ if (shm->do_make_it_fail == TRUE) return; fd = open("/proc/self/make-it-fail", O_WRONLY); if (fd == -1) return; if (write(fd, buf, 1) == -1) { if (errno != EPERM) outputerr("writing to /proc/self/make-it-fail failed! (%s)\n", strerror(errno)); else shm->do_make_it_fail = TRUE; } close(fd); }
static unsigned long handle_arg_range(struct syscallentry *entry, unsigned int argnum) { unsigned long i; unsigned long low = 0, high = 0; switch (argnum) { case 1: low = entry->low1range; high = entry->hi1range; break; case 2: low = entry->low2range; high = entry->hi2range; break; case 3: low = entry->low3range; high = entry->hi3range; break; case 4: low = entry->low4range; high = entry->hi4range; break; case 5: low = entry->low5range; high = entry->hi5range; break; case 6: low = entry->low6range; high = entry->hi6range; break; } if (high == 0) { outputerr("%s forgets to set hirange!\n", entry->name); BUG("Fix syscall definition!\n"); } i = (unsigned long) rand64() % high; if (i < low) { i += low; i &= high; } return i; }
static FILE *open_logfile(const char *logfilename) { FILE *file; char *fullpath, *p; int len = strlen(logfilename) + 2; if (logging_args) len += strlen(logging_args); p = fullpath = zmalloc(len); if (logging_args) p += snprintf(fullpath, strlen(logging_args) + 2, "%s/", logging_args); p += snprintf(p, strlen(logfilename) + 1, "%s", logfilename); unlink(fullpath); file = fopen(fullpath, "w"); if (!file) outputerr("## couldn't open logfile %s\n", fullpath); free(fullpath); return file; }
void toggle_syscall(const char *arg, bool state) { int specific_syscall = 0; char * arg_name = NULL; if (biarch == TRUE) { toggle_syscall_biarch(arg, state); return; } /* non-biarch case. */ check_user_specified_arch(arg, &arg_name, NULL, NULL); //We do not care about arch here, just to get rid of arg flags. specific_syscall = search_syscall_table(syscalls, max_nr_syscalls, arg_name); if (specific_syscall == -1) { outputerr("No idea what syscall (%s) is.\n", arg); goto out; } toggle_syscall_n(specific_syscall, state, arg, arg_name); out: clear_check_user_specified_arch(arg, &arg_name); }
double LinearRegression::train(std::vector<unsigned int> &input, std::vector<double> &target) { double totalErr = 0; test(input); for (int x = 0; x < outputs; x++) { double err = outputerr(output,target,x); totalErr+=err*err; double rateTimesError = rate*err; for (unsigned int y = 0; y < input.size(); y++) { weight[x][input[y]] -= rateTimesError; updateData &val = updates[x][input[y]]; val.n++; // double delta = err-val.mean; double delta = rateTimesError-val.mean; val.mean = val.mean+delta/val.n; val.S += delta*(err-val.mean); val.totErr += rateTimesError*rateTimesError; } weight[x][inputs] -= rateTimesError; // bias } return totalErr; }
void dump_childnos(void) { unsigned int i, j = 0; char string[512], *sptr = string; sptr += sprintf(sptr, "## pids: (%u active)\n", shm->running_childs); for (i = 0; i < max_children; i += 8) { sptr += sprintf(sptr, "%u-%u: ", i, i + 7); for (j = 0; j < 8; j++) { struct childdata *child; if (i + j > max_children) break; child = shm->children[i + j]; if (pids[child->num] == EMPTY_PIDSLOT) { sptr += sprintf(sptr, "[empty] "); } else { pid_t pid = pids[child->num]; if (pid_is_valid(pid) == FALSE) sptr += sprintf(sptr, "%s", ANSI_RED); if (pid_alive(pid) == FALSE) sptr += sprintf(sptr, "%s", ANSI_RED); sptr += sprintf(sptr, "%u %s", pid, ANSI_RESET); } } sptr += sprintf(sptr, "\n"); *sptr = '\0'; outputerr("%s", string); sptr = string; } }
static FILE * find_child_logfile_handle(pid_t pid) { int i; unsigned int j; FILE *log = NULL; i = find_childno(pid); if (i != CHILD_NOT_FOUND) { log = shm->children[i]->logfile; } else { /* This is pretty ugly, and should never happen, * but try again a second later, in case we're racing setup/teardown. * FIXME: We may not even need this now that we have proper locking; test it. */ sleep(1); i = find_childno(pid); if (i == CHILD_NOT_FOUND) { outputerr("Couldn't find child for pid %d\n", pid); return mainlogfile; } log = shm->children[i]->logfile; } if (log != NULL) return log; /* if the logfile hadn't been set, log to main. */ shm->children[i]->logfile = mainlogfile; outputerr("## child %d logfile handle was null logging to main!\n", i); outputerr("## Couldn't find logfile for pid %d\n", pid); dump_childnos(); outputerr("## Logfiles for pids: "); for_each_child(j) outputerr("%p ", shm->children[j]->logfile); outputerr("\n"); (void)fflush(stdout); sleep(5); return mainlogfile; }
/* Generate children*/ static void fork_children(void) { while (shm->running_childs < max_children) { int childno; int pid = 0; if (shm->spawn_no_more == TRUE) return; /* a new child means a new seed, or the new child * will do the same syscalls as the one in the child it's replacing. * (special case startup, or we reseed unnecessarily) */ if (shm->ready == TRUE) reseed(); /* Find a space for it in the pid map */ childno = find_childno(EMPTY_PIDSLOT); if (childno == CHILD_NOT_FOUND) { outputerr("## Pid map was full!\n"); dump_childnos(); exit_main_fail(); } fflush(stdout); pid = fork(); if (pid == 0) { /* Child process. */ struct childdata *child = shm->children[childno]; init_child(child, childno); child_process(); debugf("child %d %d exiting.\n", childno, getpid()); close_logfile(&this_child->logfile); reap_child(child->pid); _exit(EXIT_SUCCESS); } else { if (pid == -1) { /* We failed, wait for a child to exit before retrying. */ if (shm->running_childs > 0) return; output(0, "couldn't create child! (%s)\n", strerror(errno)); panic(EXIT_FORK_FAILURE); exit_main_fail(); } } shm->children[childno]->pid = pid; shm->running_childs++; debugf("Created child %d (pid:%d) [total:%d/%d]\n", childno, pid, shm->running_childs, max_children); if (shm->exit_reason != STILL_RUNNING) return; } shm->ready = TRUE; debugf("created enough children\n"); }
static void fork_children(void) { int pidslot; static char childname[17]; /* Generate children*/ while (shm->running_childs < shm->max_children) { int pid = 0; int fd; if (shm->spawn_no_more == TRUE) return; /* a new child means a new seed, or the new child * will do the same syscalls as the one in the pidslot it's replacing. * (special case startup, or we reseed unnecessarily) */ if (shm->ready == TRUE) reseed(); /* Find a space for it in the pid map */ pidslot = find_pid_slot(EMPTY_PIDSLOT); if (pidslot == PIDSLOT_NOT_FOUND) { outputerr("## Pid map was full!\n"); dump_pid_slots(); exit(EXIT_FAILURE); } if (logging == TRUE) { fd = fileno(shm->logfiles[pidslot]); if (ftruncate(fd, 0) == 0) lseek(fd, 0, SEEK_SET); } (void)alarm(0); fflush(stdout); pid = fork(); if (pid != 0) shm->pids[pidslot] = pid; else { /* Child process. */ int ret = 0; mask_signals_child(); memset(childname, 0, sizeof(childname)); sprintf(childname, "trinity-child%d", pidslot); prctl(PR_SET_NAME, (unsigned long) &childname); oom_score_adj(500); /* Wait for parent to set our pidslot */ while (shm->pids[pidslot] != getpid()) { /* Make sure parent is actually alive to wait for us. */ ret = pid_alive(shm->mainpid); if (ret != 0) { shm->exit_reason = EXIT_SHM_CORRUPTION; outputerr(BUGTXT "parent (%d) went away!\n", shm->mainpid); sleep(20000); } } /* Wait for all the children to start up. */ while (shm->ready == FALSE) sleep(1); init_child(pidslot); ret = child_process(pidslot); output(1, "child exiting.\n"); _exit(ret); } shm->running_childs++; debugf("Created child %d in pidslot %d [total:%d/%d]\n", shm->pids[pidslot], pidslot, shm->running_childs, shm->max_children); if (shm->exit_reason != STILL_RUNNING) return; } shm->ready = TRUE; debugf("created enough children\n"); }
static void handle_child(pid_t childpid, int childstatus) { unsigned int i; int slot; switch (childpid) { case 0: //debugf("Nothing changed. children:%d\n", shm->running_childs); break; case -1: if (shm->exit_reason != STILL_RUNNING) return; if (errno == ECHILD) { debugf("All children exited!\n"); for_each_pidslot(i) { if (shm->pids[i] != EMPTY_PIDSLOT) { if (pid_alive(shm->pids[i]) == -1) { debugf("Removing %d from pidmap\n", shm->pids[i]); shm->pids[i] = EMPTY_PIDSLOT; shm->running_childs--; } else { debugf("%d looks still alive! ignoring.\n", shm->pids[i]); } } } break; } output(0, "error! (%s)\n", strerror(errno)); break; default: debugf("Something happened to pid %d\n", childpid); if (WIFEXITED(childstatus)) { slot = find_pid_slot(childpid); if (slot == PIDSLOT_NOT_FOUND) { /* If we reaped it, it wouldn't show up, so check that. */ if (shm->last_reaped != childpid) { outputerr("## Couldn't find pid slot for %d\n", childpid); shm->exit_reason = EXIT_LOST_PID_SLOT; dump_pid_slots(); } } else { debugf("Child %d exited after %ld syscalls.\n", childpid, shm->child_syscall_count[slot]); reap_child(childpid); } break; } else if (WIFSIGNALED(childstatus)) { switch (WTERMSIG(childstatus)) { case SIGALRM: debugf("got a alarm signal from pid %d\n", childpid); break; case SIGFPE: case SIGSEGV: case SIGKILL: case SIGPIPE: case SIGABRT: debugf("got a signal from pid %d (%s)\n", childpid, strsignal(WTERMSIG(childstatus))); reap_child(childpid); break; default: debugf("** Child got an unhandled signal (%d)\n", WTERMSIG(childstatus)); break; } break; } else if (WIFSTOPPED(childstatus)) { switch (WSTOPSIG(childstatus)) { case SIGALRM: debugf("got an alarm signal from pid %d\n", childpid); break; case SIGSTOP: debugf("Sending PTRACE_DETACH (and then KILL)\n"); ptrace(PTRACE_DETACH, childpid, NULL, NULL); kill(childpid, SIGKILL); reap_child(childpid); break; case SIGFPE: case SIGSEGV: case SIGKILL: case SIGPIPE: case SIGABRT: debugf("Child %d was stopped by %s\n", childpid, strsignal(WTERMSIG(childstatus))); reap_child(childpid); break; default: debugf("Child %d was stopped by unhandled signal (%s).\n", childpid, strsignal(WSTOPSIG(childstatus))); break; } break; } else if (WIFCONTINUED(childstatus)) { break; } else { output(0, "erk, wtf\n"); } }
static int parse_format(const char *string, int *field_type, unsigned long long *mask) { int i, secondnum, bits; char format_string[BUFSIZ]; *mask=0; /* get format */ /* according to Documentation/ABI/testing/sysfs-bus-event_source-devices-format */ /* the format is something like config1:1,6-10,44 */ i=0; while(1) { format_string[i]=string[i]; if (string[i]==':') { format_string[i]=0; break; } if (string[i]==0) break; i++; } if (!strcmp(format_string,"config")) { *field_type=FIELD_CONFIG; } else if (!strcmp(format_string,"config1")) { *field_type=FIELD_CONFIG1; } else if (!strcmp(format_string,"config2")) { *field_type=FIELD_CONFIG2; } else { *field_type=FIELD_UNKNOWN; } while(1) { int firstnum, shift; /* Read first number */ i++; firstnum=0; while(1) { if (string[i]==0) break; if (string[i]=='-') break; if (string[i]==',') break; if ((string[i]<'0') || (string[i]>'9')) { outputerr("Unknown format char %c\n", string[i]); return -1; } firstnum*=10; firstnum+=(string[i])-'0'; i++; } shift=firstnum; /* check if no second num */ if ((string[i]==0) || (string[i]==',')) { bits=1; } else { /* Read second number */ i++; secondnum=0; while(1) { if (string[i]==0) break; if (string[i]=='-') break; if (string[i]==',') break; if ((string[i]<'0') || (string[i]>'9')) { outputerr("Unknown format char %c\n", string[i]); return -1; } secondnum*=10; secondnum+=(string[i])-'0'; i++; } bits=(secondnum-firstnum)+1; } if (bits==64) { *mask|=0xffffffffffffffffULL; } else { *mask|=((1ULL<<bits)-1)<<shift; } if (string[i]==0) break; } return 0; }
static void lock_cachefile(int cachefile, int type) { struct flock fl = { .l_len = 0, .l_start = 0, .l_whence = SEEK_SET, }; fl.l_pid = getpid(); fl.l_type = type; if (verbose) output(2, "waiting on lock for cachefile\n"); if (fcntl(cachefile, F_SETLKW, &fl) == -1) { perror("fcntl F_SETLKW"); exit(1); } if (verbose) output(2, "took lock for cachefile\n"); } static void unlock_cachefile(int cachefile) { struct flock fl = { .l_len = 0, .l_start = 0, .l_whence = SEEK_SET, }; fl.l_pid = getpid(); fl.l_type = F_UNLCK; if (fcntl(cachefile, F_SETLK, &fl) == -1) { perror("fcntl F_UNLCK F_SETLK "); exit(1); } if (verbose) output(2, "dropped lock for cachefile\n"); } static void generate_sockets(void) { int fd, n; int cachefile; unsigned int nr_to_create = NR_SOCKET_FDS; unsigned int buffer[3]; cachefile = creat(cachefilename, S_IWUSR|S_IRUSR); if (cachefile < 0) { outputerr("Couldn't open cachefile for writing! (%s)\n", strerror(errno)); exit(EXIT_FAILURE); } lock_cachefile(cachefile, F_WRLCK); /* * Don't loop forever if all protos all are disabled. */ if (!do_specific_proto) { for (n = 0; n < (int)ARRAY_SIZE(no_protos); n++) { if (!no_protos[n]) break; } if (n >= (int)ARRAY_SIZE(no_protos)) nr_to_create = 0; } while (nr_to_create > 0) { struct socket_triplet st; if (shm->exit_reason != STILL_RUNNING) { close(cachefile); return; } for (st.family = 0; st.family < TRINITY_PF_MAX; st.family++) { if (do_specific_proto == TRUE) st.family = specific_proto; if (get_proto_name(st.family) == NULL) goto skip; BUG_ON(st.family >= ARRAY_SIZE(no_protos)); if (no_protos[st.family]) goto skip; if (sanitise_socket_triplet(&st) == -1) rand_proto_type(&st); fd = open_socket(st.family, st.type, st.protocol); if (fd > -1) { nr_to_create--; buffer[0] = st.family; buffer[1] = st.type; buffer[2] = st.protocol; n = write(cachefile, &buffer, sizeof(int) * 3); if (n == -1) { outputerr("something went wrong writing the cachefile!\n"); exit(EXIT_FAILURE); } if (nr_to_create == 0) goto done; } else { //outputerr("Couldn't open family:%d (%s)\n", st.family, get_proto_name(st.family)); } skip: /* check for ctrl-c */ if (shm->exit_reason != STILL_RUNNING) return; //FIXME: If we've passed -P and we're spinning here without making progress // then we should abort after a few hundred loops. } } done: unlock_cachefile(cachefile); output(1, "created %d sockets\n", nr_sockets); close(cachefile); } void close_sockets(void) { unsigned int i; int fd; int r = 0; struct linger ling = { .l_onoff = FALSE, .l_linger = 0 }; for (i = 0; i < nr_sockets; i++) { //FIXME: This is a workaround for a weird bug where we hang forevre // waiting for bluetooth sockets when we setsockopt. // Hopefully at some point we can remove this when someone figures out what's going on. if (shm->sockets[i].triplet.family == PF_BLUETOOTH) continue; /* Grab an fd, and nuke it before someone else uses it. */ fd = shm->sockets[i].fd; shm->sockets[i].fd = 0; /* disable linger */ r = setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)); if (r) perror("setsockopt"); r = shutdown(fd, SHUT_RDWR); if (r) perror("shutdown"); if (close(fd) != 0) output(1, "failed to close socket [%d:%d:%d].(%s)\n", shm->sockets[i].triplet.family, shm->sockets[i].triplet.type, shm->sockets[i].triplet.protocol, strerror(errno)); } nr_sockets = 0; } void open_sockets(void) { int cachefile; unsigned int domain, type, protocol; unsigned int buffer[3]; int bytesread=-1; int fd; cachefile = open(cachefilename, O_RDONLY); if (cachefile < 0) { output(1, "Couldn't find socket cachefile. Regenerating.\n"); generate_sockets(); return; } lock_cachefile(cachefile, F_RDLCK); while (bytesread != 0) { bytesread = read(cachefile, buffer, sizeof(int) * 3); if (bytesread == 0) break; domain = buffer[0]; type = buffer[1]; protocol = buffer[2]; if ((do_specific_proto == TRUE && domain != specific_proto) || (domain < ARRAY_SIZE(no_protos) && no_protos[domain] == TRUE)) { output(1, "ignoring socket cachefile due to specific " "protocol request (or protocol disabled), " "and stale data in cachefile.\n"); regenerate: unlock_cachefile(cachefile); /* drop the reader lock. */ close(cachefile); unlink(cachefilename); generate_sockets(); return; } fd = open_socket(domain, type, protocol); if (fd < 0) { output(1, "Cachefile is stale. Need to regenerate.\n"); close_sockets(); goto regenerate; } /* check for ctrl-c */ if (shm->exit_reason != STILL_RUNNING) { close(cachefile); return; } } if (nr_sockets < NR_SOCKET_FDS) { output(1, "Insufficient sockets in cachefile (%d). Regenerating.\n", nr_sockets); goto regenerate; } output(1, "%d sockets created based on info from socket cachefile.\n", nr_sockets); unlock_cachefile(cachefile); close(cachefile); }
int CreateDatabase(DBProvider *pdb) { char buffer[10240]; char *pBuf = buffer; char line[1024]; gchar *szFile = BuildFilename("gnubg.sql"); FILE *fp = g_fopen(szFile, "r"); if (!fp) { g_free(szFile); return FALSE; } buffer[0] = '\0'; while (fgets(line, sizeof(line), fp) != NULL) { char *pLine = line + strlen(line) - 1; while (pLine >= line && isspace(*pLine)) { *pLine = '\0'; pLine--; } pLine = line; while (isspace(*pLine)) pLine++; if (pLine[0] != '-' || pLine[1] != '-') { size_t len = strlen(pLine); if (len > 0) { strcat(buffer, pLine); pBuf += len; if (pLine[len - 1] == ';') { if (!pdb->UpdateCommand(buffer)) { fclose(fp); g_free(szFile); return FALSE; } pBuf = buffer; buffer[0] = '\0'; } } } } if (ferror(fp)) { outputerr(szFile); g_free(szFile); fclose(fp); return FALSE; } g_free(szFile); fclose(fp); pBuf = g_strdup_printf("INSERT INTO control VALUES ('version', %d)", DB_VERSION); pdb->UpdateCommand(pBuf); g_free(pBuf); pdb->Commit(); return TRUE; }
/* Generate children*/ static void fork_children(void) { while (shm->running_childs < max_children) { int pidslot; int pid = 0; if (shm->spawn_no_more == TRUE) return; /* a new child means a new seed, or the new child * will do the same syscalls as the one in the pidslot it's replacing. * (special case startup, or we reseed unnecessarily) */ if (shm->ready == TRUE) reseed(); /* Find a space for it in the pid map */ pidslot = find_pid_slot(EMPTY_PIDSLOT); if (pidslot == PIDSLOT_NOT_FOUND) { outputerr("## Pid map was full!\n"); dump_pid_slots(); exit(EXIT_FAILURE); } if (logging == TRUE) { int fd; fd = fileno(shm->logfiles[pidslot]); if (ftruncate(fd, 0) == 0) lseek(fd, 0, SEEK_SET); } (void)alarm(0); fflush(stdout); pid = fork(); if (pid == 0) { /* Child process. */ init_child(pidslot); child_process(pidslot); debugf("child %d exiting.\n", pidslot); _exit(EXIT_SUCCESS); } else { if (pid == -1) { output(0, "couldn't create child! (%s)\n", strerror(errno)); shm->exit_reason = EXIT_FORK_FAILURE; exit(EXIT_FAILURE); } } shm->pids[pidslot] = pid; shm->running_childs++; debugf("Created child %d in pidslot %d [total:%d/%d]\n", shm->pids[pidslot], pidslot, shm->running_childs, max_children); if (shm->exit_reason != STILL_RUNNING) return; } shm->ready = TRUE; debugf("created enough children\n"); }