int main(int argc, char *argv[]) { char *arg, *cfgname, *csvname; int ai, testnums[256], ti, num; setlocale(LC_CTYPE, ""); cfgname = csvname = NULL; for (ai = 1; ai < argc; ai++) { arg = argv[ai]; if (strcmp("-f", arg) == 0) { arg = argv[++ai]; if (ai >= argc) { PMNF(EINVAL, ": -f requires a .cfg filename"); goto err; } cfgname = arg; } else if (strcmp("-t", arg) == 0) { arg = argv[++ai]; if (ai >= argc) { PMNF(EINVAL, ": -t requires a .csv filename"); goto err; } csvname = arg; } else { break; } } if (cfgname == NULL) { cfgname = "tmba.cfg"; } if (csvname == NULL) { csvname = "tmba.csv"; } ti = 0; while (ai < argc) { arg = argv[ai++]; if ((num = strtol(arg, NULL, 10)) == LONG_MIN || num == LONG_MAX) { PMNF(errno, ": Invalid test number: %s", arg); goto err; } testnums[ti++] = num; } if (run_suite(cfgname, csvname, testnums, ti) == -1) { AMSG(""); goto err; } return EXIT_SUCCESS; err: MMSG("usage: %s [-f <suite.cfg>] [-t <suite.csv>] [<test num> <test num> <test num> ...]\n", argv[0]); return EXIT_FAILURE; }
int symload(struct idl *idl, const char *filename) { FILE *in; int n; unsigned char buf[512], *row[4]; if ((in = fopen(filename, "r")) == NULL) { PMNF(errno, ": %s", filename); return -1; } while ((n = csv_row_fread(in, buf, 512, row, 4, '\t', CSV_TRIM | CSV_QUOTES)) > 0) { struct sym *sym; if (*row[0] == '\0' || *row[0] == '#') { continue; } if ((sym = symadd(idl, row[0], row[1], row[2], atoi(row[3]))) == NULL) { AMSG(""); return -1; } sym->flags |= FLAGS_PRIMATIVE; } fclose(in); if (n == -1) { AMSG(""); return -1; } return 0; }
TOKFILE * tok_fopen(const char *filename) { TOKFILE *tf; if ((tf = calloc(1, sizeof *tf)) == NULL) { PMNO(errno); return NULL; } if ((tf->in = fopen(filename, "r")) == NULL) { PMNF(errno, ": %s", filename); free(tf); return NULL; } tf->line = 1; return tf; }
static int run_one(struct idl *idl, struct sym *iface, const char *outname, int (*emit)(struct idl *, struct sym *)) { if ((idl->out = fopen(outname, "w")) == NULL) { PMNF(errno, ": %s", outname); return -1; } if (emit(idl, iface) == -1) { AMSG(""); return -1; } fclose(idl->out); return 0; }
void * open_mmap(const char *name, int flags, int mode, size_t size) { char *fname, buf[32] = "/tmp/"; int i, fd, prot = PROT_READ; void *ret; fname = buf + 5; for (i = 0; i < 22 && name[i]; i++) { if (name[i] == '.' || name[i] == '/') { errno = EINVAL; PMNO(errno); return NULL; } fname[i] = name[i]; } strcpy(fname + i, ".shm"); if ((fd = open(buf, flags, mode)) == -1 || (mode && fchmod(fd, mode) == -1)) { PMNF(errno, ": %s", buf); return NULL; } if (ftruncate(fd, size) == -1) { close(i); PMNO(errno); return NULL; } if ((flags & O_RDWR)) { prot |= PROT_WRITE; } if ((ret = mmap(NULL, size, prot, MAP_SHARED, fd, 0)) == MAP_FAILED) { PMNO(errno); return NULL; } close(fd); return ret; }
int suba_free(void *suba0, void *ptr) { struct allocator *suba = suba0; struct cell *c1, *c2, *c3; ref_t ref; int j1, j2; if (!ptr) return 0; if (!suba_ref(suba, ptr)) { PMNO(errno = EFAULT); return -1; } /* splice the cell back into the list */ c1 = SADR(suba, suba->tail); c2 = P2C(ptr); if (c2->size > suba->max_free || (ref = suba_ref(suba, c2)) == 0) { PMNF(errno = EINVAL, ": %p: %d", ptr, c2->size); return -1; } // CHDK counters suba->allocated_size -= POFF + c2->size; suba->allocated_count--; // old suba counter // suba->free_total += POFF + c2->size; /* c2->stk[0] = NULL; suba_print_cell(suba, " FREE", c2); */ if (c2 > c1) { /* append to end of list */ if (ISADJ(c1,c2)) { /* join with last cell */ c1->size += POFF + c2->size; return 0; } c2->next = c1->next; suba->tail = c1->next = ref; return 0; } while (c1->next < ref) { /* find insertion point */ if (c1->next < POFF) { PMNF(errno = EINVAL, ": next ref corrupted: %d", c1->next); return -1; } c1 = SADR(suba, c1->next); } c3 = SADR(suba, c1->next); j1 = ISADJ(c1,c2); /* c1 and c2 need to be joined */ j2 = ISADJ(c2,c3); /* c2 and c3 need to be joined */ if (j1) { if (j2) { /* splice all three cells together */ if (SREF(suba, c3) == suba->tail) { suba->tail = SREF(suba, c1); } c1->next = c3->next; c1->size += POFF + c3->size; } c1->size += POFF + c2->size; } else { if (j2) { if (SREF(suba, c3) == suba->tail) { suba->tail = ref; } c2->next = c3->next == SREF(suba, c3) ? ref : c3->next; c2->size += POFF + c3->size; } else { c2->next = c1->next; } c1->next = ref; } return 0; }
void * suba_alloc(struct allocator *suba, size_t size, int zero) { struct cell *c1, *c2, *c3; size_t s = size; int reclaim = 0; size = size < suba->mincell ? suba->mincell : ALIGN(size); again: if (reclaim) { int progress = 0; //if (suba->reclaim && suba->reclaim_depth <= RECLAIM_DEPTH_MAX) { // suba->reclaim_depth++; // progress = suba->reclaim(suba, suba->reclaim_arg, reclaim); // suba->reclaim_depth--; //} if (!progress) { PMNO(errno = ENOMEM); return NULL; } } c2 = SADR(suba, suba->tail); for ( ;; ) { c1 = c2; if ((c2 = suba_addr(suba, c1->next)) == NULL) { PMNF(errno = EFAULT, ": 0x%08x", c1->next); return NULL; } if (c2->size >= size) { break; /* found a cell large enough */ } if (c1->next == suba->tail) { reclaim++; goto again; } } if (c2->size > (POFF + size + suba->mincell)) { /* split new cell */ c3 = (struct cell *)(C2P(c2) + size); c3->size = c2->size - (size + POFF); if (c1 == c2) { c1 = c3; } else { c3->next = c2->next; } c1->next = SREF(suba, c3); c2->size = size; if (c2 == SADR(suba, suba->tail)) { suba->tail = SREF(suba, c3); } } else if (c1->next == suba->tail) { /* never use the last cell! */ reclaim++; goto again; } else { /* use the entire cell */ c1->next = c2->next; } // CHDK counters suba->allocated_size += POFF + c2->size; suba->allocated_count++; if(suba->allocated_size > suba->allocated_peak) { suba->allocated_peak = suba->allocated_size; } // old suba counters /* suba->alloc_total += POFF + c2->size; suba->size_total += s; */ return zero ? memset(C2P(c2), 0, size) : C2P(c2); }
int run_suite(const char *cfgname, const char *csvname, int testnums[], int tlen) { struct cfg *cfg; FILE *csv; unsigned char buf[4096], *row[32]; int tnum, ti, ret, flags; if ((cfg = cfg_new(NULL)) == NULL || cfg_load(cfg, cfgname)) { AMSG(": %s", cfgname); return -1; } if ((csv = fopen(csvname, "r")) == NULL) { PMNF(errno, ": %s", csvname); return -1; } while ((ret = csv_row_fread(csv, buf, 4096, row, 32, ',', CSV_TRIM | CSV_QUOTES)) > 0) { if ((flags = strtol(row[1], NULL, 10)) == LONG_MIN || flags == LONG_MAX) { PMNF(errno, ": Invalid test flags: %s", row[1]); return -1; } if (flags == 0) { continue; } if ((tnum = strtol(row[0], NULL, 10)) == LONG_MIN || tnum == LONG_MAX) { PMNF(errno, ": Invalid test number: %s", row[0]); return -1; } if (tlen) { for (ti = 0; ti < tlen; ti++) { if (tnum == testnums[ti]) { break; } } if (ti == tlen) { continue; } } for (ti = 0; test_tbl[ti].test; ti++) { if (tnum == test_tbl[ti].num) { break; } } if (test_tbl[ti].test == NULL) { PMSG("Test not found: %d", tnum); return -1; } errno = 0; fprintf(stderr, "%d:%s: ", tnum, row[2]); fflush(stderr); if (test_tbl[ti].test(flags > 1 ? flags : 0, cfg, (char **)row + 4) == 0) { fprintf(stderr, "pass\n"); } else { MMSG("%d failed", tnum); } } fclose(csv); cfg_del(cfg); return ret; }
static int csv_parse_str(struct sinput *in, unsigned char *buf, size_t bn, unsigned char *row[], int rn, int sep, int flags) { int trim, quotes, ch, state, r, j, t, inquotes; trim = flags & CSV_TRIM; quotes = flags & CSV_QUOTES; state = ST_START; inquotes = 0; ch = r = j = t = 0; memset(row, 0, sizeof(unsigned char *) * rn); while (rn && bn && (ch = snextch(in)) > 0) { switch (state) { case ST_START: if (ch != '\n' && ch != sep && isspace(ch)) { if (!trim) { buf[j++] = ch; bn--; t = j; } break; } else if (quotes && ch == '"') { j = t = 0; state = ST_COLLECT; inquotes = 1; break; } state = ST_COLLECT; case ST_COLLECT: if (inquotes) { if (ch == '"') { state = ST_END_QUOTE; break; } } else if (ch == sep || ch == '\n') { row[r++] = buf; rn--; if (ch == '\n' && t && buf[t - 1] == '\r') { t--; bn++; /* crlf -> lf */ } buf[t] = '\0'; bn--; buf += t + 1; j = t = 0; state = ST_START; inquotes = 0; if (ch == '\n') { rn = 0; } break; } else if (quotes && ch == '"') { PMNF(errno = EILSEQ, ": unexpected quote in element %d", (r + 1)); return -1; } buf[j++] = ch; bn--; if (!trim || isspace(ch) == 0) { t = j; } break; case ST_TAILSPACE: case ST_END_QUOTE: if (ch == sep || ch == '\n') { row[r++] = buf; rn--; buf[j] = '\0'; bn--; buf += j + 1; j = t = 0; state = ST_START; inquotes = 0; if (ch == '\n') { rn = 0; } break; } else if (quotes && ch == '"' && state != ST_TAILSPACE) { buf[j++] = '"'; bn--; /* nope, just an escaped quote */ t = j; state = ST_COLLECT; break; } else if (isspace(ch)) { state = ST_TAILSPACE; break; } errno = EILSEQ; PMNF(errno, ": bad end quote in element %d", (r + 1)); return -1; } } if (ch == -1) { AMSG(""); return -1; } if (bn == 0) { PMNO(errno = E2BIG); return -1; } if (rn) { if (inquotes && state != ST_END_QUOTE) { PMNO(errno = EILSEQ); return -1; } row[r] = buf; buf[t] = '\0'; } return in->count; }
int tokget(TOKFILE *in, char *dst, char *dlim) { char *start = dst; int ch; if (in->state == -1) { *dst = '\0'; return 0; } while (dst < dlim) { ch = fgetc(in->in); if (ch == '#') { while ((ch = fgetc(in->in)) != '\n') { if (ch == EOF) { *dst = '\0'; return 0; } } } else if (ch == '\n') { in->line++; } switch (in->state) { case 0: if (ch == EOF) { in->state = -1; *dst = '\0'; return 0; } else if (isspace(ch)) { break; } in->state = 1; case 1: if (ch == EOF) { in->state = -1; *dst = '\0'; return 0; } else if (istokchar(ch)) { *dst++ = ch; *dst = '\0'; in->state = 0; return 1; } in->state = 2; case 2: if (isspace(ch) || istokchar(ch) || ch == EOF) { if (ch == EOF) { in->state = -1; } else if (ch == '*' && (dst - start) == 1 && *start == '/') { in->state = 3; /* comment */ dst = start; break; } else { ungetc(ch, in->in); in->state = 0; } *dst = '\0'; return dst - start; } *dst++ = ch; break; case 3: if (ch == '*') { in->state = 4; } break; case 4: if (ch != '*') { in->state = ch != '/' ? 3 : 0; } break; default: errno = EINVAL; PMNF(errno, ": invalid TOKFILE state: %d", in->state); in->state = -1; return -1; } } if (dst == dlim) { errno = ERANGE; PMNO(errno); return -1; } return 0; }
pid_t daemonize(mode_t mask, const char *rundir, const char *pidpath, const char *lockpath, const char *logpath) { pid_t pid; int fd; if (getppid() == 1) { /* already a daemon */ return 0; } if ((pid = fork())) { return pid; } /* child (daemon) continues */ setsid(); /* obtain a new process group */ umask(mask); /* set newly created file permissions */ /* close all descriptors */ for (fd = getdtablesize(); fd >= 0; fd--) { close(fd); } /* but stdin, stdout, and stderr are redirected to /dev/null */ if ((fd = open("/dev/null", O_RDWR)) != 0 || dup(fd) != 1 || dup(fd) != 2) { return -1; } if (logpath) { /* open the logfile */ time_t start = time(NULL); if ((logfp = fopen(logpath, "a")) == NULL) { PMNF(errno, ": %s", logpath); return -1; } msgno_hdlr = daemonlog; daemonlog("log started: %s", ctime(&start)); } if (lockpath) { if ((fd = open(lockpath, O_RDWR | O_CREAT, 0640)) == -1) { PMNF(errno, ": %s", lockpath); return -1; } if (lockf(fd, F_TLOCK, 0) == -1) { /* can not lock */ PMNF(errno, ": %s: Server already running.", lockpath); return -1; } } /* first instance continues */ if (pidpath) { char str[10]; if ((fd = open(pidpath, O_RDWR | O_CREAT, 0640)) == -1) { PMNO(errno); return -1; } sprintf(str, "%d\n", getpid()); if (write(fd, str, strlen(str)) == -1) { /* write pid to lockfile */ PMNO(errno); return -1; } close(fd); } if (rundir && chdir(rundir) == -1) { /* change running directory */ PMNF(errno, ": %s", rundir); return -1; } signal(SIGTSTP,SIG_IGN); /* ignore tty signals */ signal(SIGTTOU,SIG_IGN); signal(SIGTTIN,SIG_IGN); return 0; }
int HashmapCount(int verbose, struct cfg *cfg, char *args[]) { struct test t; char *mem = NULL; int ret = 0, fd = 0, data; int useal = atoi(args[0]); struct stat st; void *mm; if (useal) { if ((mem = malloc(0xFFFFFF)) == NULL || (t.al = suba_init(mem, 0xFFFFFF, 1, 0)) == NULL) { AMSG(""); ret = -1; goto err; } } else { t.al = NULL; } if ((t.words = hashmap_new(hash_str, (cmp_fn)strcmp, NULL, t.al)) == NULL || (fd = open(args[1], 0)) == -1 || fstat(fd, &st) == -1) { AMSG(""); ret = -1; goto err; } if ((t.src = mm = mmap(NULL, (int)st.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)) == NULL) { AMSG(""); ret = -1; goto err; } t.slim = t.src + st.st_size; if (load_words(&t) == -1) { AMSG(""); ret = -1; goto err; } if ((data = (int)hashmap_get(t.words, args[2])) == 0 || atoi(args[3]) != data || (data = (int)hashmap_get(t.words, args[4])) == 0 || atoi(args[5]) != data) { errno = ERANGE; PMNF(errno, ": %d != %d", atoi(args[3]), data); ret = -1; goto err; } if (verbose) print_values(t.words); err: munmap(mm, st.st_size); if (fd) close(fd); hashmap_del(t.words, NULL, NULL, NULL); free(mem); cfg = NULL; return ret; }