long powerpc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { struct reg regs; struct freebsd_syscall *fsc; struct syscall *sc; lwpid_t tid; long retval; int errorp, i; if (trussinfo->curthread->fsc == NULL) return (-1); tid = trussinfo->curthread->tid; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "\n"); return (-1); } retval = regs.fixreg[3]; errorp = !!(regs.cr & 0x10000000); /* * This code, while simpler than the initial versions I used, could * stand some significant cleaning. */ fsc = trussinfo->curthread->fsc; sc = fsc->sc; if (!sc) { for (i = 0; i < fsc->nargs; i++) asprintf(&fsc->s_args[i], "0x%lx", fsc->args[i]); } else { /* * Here, we only look for arguments that have OUT masked in -- * otherwise, they were handled in the syscall_entry function. */ for (i = 0; i < sc->nargs; i++) { char *temp; if (sc->args[i].type & OUT) { /* * If an error occurred, then don't bother * getting the data; it may not be valid. */ if (errorp) { asprintf(&temp, "0x%lx", fsc->args[sc->args[i].offset]); } else { temp = print_arg(&sc->args[i], fsc->args, retval, trussinfo); } fsc->s_args[i] = temp; } } } if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || strcmp(fsc->name, "exit") == 0)) trussinfo->curthread->in_syscall = 1; /* * It would probably be a good idea to merge the error handling, * but that complicates things considerably. */ print_syscall_ret(trussinfo, fsc->name, fsc->nargs, fsc->s_args, errorp, retval, fsc->sc); free_fsc(fsc); return (retval); }
void arg_printusage (struct getargs *args, size_t num_args, const char *progname, const char *extra_string) { unsigned int i; size_t max_len = 0; char buf[128]; int col = 0, columns; #ifdef HAVE___PROGNAME if (progname == NULL) progname = __progname; #endif if (progname == NULL) progname = ""; #ifdef GETARGMANDOC if(getenv("GETARGMANDOC")){ mandoc_template(args, num_args, progname, extra_string); return; } #endif columns = 80; /* Always assume that the window is 80 chars wide */ col = 0; col += fprintf (stderr, "Usage: %s", progname); for (i = 0; i < num_args; ++i) { size_t len = 0; if (args[i].long_name) { buf[0] = '\0'; strlcat(buf, "[--", sizeof(buf)); len += 2; if(args[i].type == arg_negative_flag) { strlcat(buf, "no-", sizeof(buf)); len += 3; } strlcat(buf, args[i].long_name, sizeof(buf)); len += strlen(args[i].long_name); len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 0, 1, &args[i]); strlcat(buf, "]", sizeof(buf)); if(args[i].type == arg_strings) strlcat(buf, "...", sizeof(buf)); col = check_column(stderr, col, (int)strlen(buf) + 1, columns); col += fprintf(stderr, " %s", buf); } if (args[i].short_name) { basestring_snprintf(buf, sizeof(buf), "[-%c", args[i].short_name); len += 2; len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 0, 0, &args[i]); strlcat(buf, "]", sizeof(buf)); if(args[i].type == arg_strings) strlcat(buf, "...", sizeof(buf)); col = check_column(stderr, col, (int)strlen(buf) + 1, columns); col += fprintf(stderr, " %s", buf); } if (args[i].long_name && args[i].short_name) len += 2; /* ", " */ max_len = max(max_len, len); } if (extra_string) { col = check_column(stderr, col, (int)strlen(extra_string) + 1, columns); fprintf (stderr, " %s\n", extra_string); } else fprintf (stderr, "\n"); for (i = 0; i < num_args; ++i) { if (args[i].help) { size_t count = 0; if (args[i].short_name) { count += fprintf (stderr, "-%c", args[i].short_name); print_arg (buf, sizeof(buf), 0, 0, &args[i]); count += fprintf(stderr, "%s", buf); } if (args[i].short_name && args[i].long_name) count += fprintf (stderr, ", "); if (args[i].long_name) { count += fprintf (stderr, "--"); if (args[i].type == arg_negative_flag) count += fprintf (stderr, "no-"); count += fprintf (stderr, "%s", args[i].long_name); print_arg (buf, sizeof(buf), 0, 1, &args[i]); count += fprintf(stderr, "%s", buf); } while(count++ <= max_len) putc (' ', stderr); fprintf (stderr, "%s\n", args[i].help); } } }
void powerpc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { struct ptrace_io_desc iorequest; struct reg regs; struct freebsd_syscall *fsc; struct syscall *sc; void *args; lwpid_t tid; int i, regargs, syscall_num; tid = trussinfo->curthread->tid; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } /* * FreeBSD has two special kinds of system call redirctions -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. */ regargs = NARGREG; syscall_num = regs.fixreg[0]; args = ®s.fixreg[3]; if (syscall_num == SYS_syscall || syscall_num == SYS___syscall) { args = ®s.fixreg[4]; regargs -= 1; syscall_num = regs.fixreg[3]; } fsc = alloc_fsc(); if (fsc == NULL) return; fsc->number = syscall_num; fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; if (!fsc->name) { fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); } if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && (strcmp(fsc->name, "fork") == 0 || strcmp(fsc->name, "rfork") == 0 || strcmp(fsc->name, "vfork") == 0)) trussinfo->curthread->in_fork = 1; if (nargs == 0) return; fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); if (nargs > regargs) { memmove(&fsc->args[0], args, regargs * sizeof(fsc->args[0])); iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)(regs.fixreg[1] + 48); iorequest.piod_addr = &fsc->args[regargs]; iorequest.piod_len = (nargs - regargs) * sizeof(fsc->args[0]); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) return; } else memmove(&fsc->args[0], args, nargs * sizeof(fsc->args[0])); sc = get_syscall(fsc->name); if (sc) fsc->nargs = sc->nargs; else { #if DEBUG fprintf(trussinfo->outfile, "unknown syscall %s -- setting " "args to %d\n", fsc->name, nargs); #endif fsc->nargs = nargs; } fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); fsc->sc = sc; /* * At this point, we set up the system call arguments. * We ignore any OUT ones, however -- those are arguments that * are set by the system call, and so are probably meaningless * now. This doesn't currently support arguments that are * passed in *and* out, however. */ if (fsc->name) { #if DEBUG fprintf(stderr, "syscall %s(", fsc->name); #endif for (i = 0; i < fsc->nargs; i++) { #if DEBUG fprintf(stderr, "0x%x%s", sc ? fsc->args[sc->args[i].offset] : fsc->args[i], i < (fsc->nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { fsc->s_args[i] = print_arg(&sc->args[i], fsc->args, 0, trussinfo); } } #if DEBUG fprintf(stderr, ")\n"); #endif } #if DEBUG fprintf(trussinfo->outfile, "\n"); #endif if (fsc->name && (strcmp(fsc->name, "execve") == 0 || strcmp(fsc->name, "exit") == 0)) { /* * XXX * This could be done in a more general * manner but it still wouldn't be very pretty. */ if (strcmp(fsc->name, "execve") == 0) { if ((trussinfo->flags & EXECVEARGS) == 0) { if (fsc->s_args[1]) { free(fsc->s_args[1]); fsc->s_args[1] = NULL; } } if ((trussinfo->flags & EXECVEENVS) == 0) { if (fsc->s_args[2]) { free(fsc->s_args[2]); fsc->s_args[2] = NULL; } } } } trussinfo->curthread->fsc = fsc; }
static void mandoc_template(struct agetargs *args, const char *extra_string, int style) { struct agetargs *arg; char timestr[64], cmd[64]; const char *p; time_t t; extern char *__progname; printf(".\\\" Things to fix:\n"); printf(".\\\" * correct section, and operating system\n"); printf(".\\\" * remove Op from mandatory flags\n"); printf(".\\\" * use better macros for arguments (like .Pa for files)\n"); printf(".\\\"\n"); t = time(NULL); strftime(timestr, sizeof(timestr), "%b %d, %Y", localtime(&t)); printf(".Dd %s\n", timestr); p = strrchr(__progname, '/'); if(p) p++; else p = __progname; strncpy(cmd, p, sizeof(cmd)); cmd[sizeof(cmd)-1] = '\0'; strupr(cmd); printf(".Dt %s SECTION\n", cmd); printf(".Os OPERATING_SYSTEM\n"); printf(".Sh NAME\n"); printf(".Nm %s\n", p); printf(".Nd\n"); printf("in search of a description\n"); printf(".Sh SYNOPSIS\n"); printf(".Nm\n"); for(arg = args; arg->type; arg++) { if(arg->short_name){ printf(".Op Fl %c", arg->short_name); print_arg(stdout, 1, 0, args, style); printf("\n"); } if(arg->long_name){ printf(".Op Fl %s%s", style & AARG_TRANSLONG ? "" : "-", arg->long_name); print_arg(stdout, 1, 1, args, style); printf("\n"); } /* if(arg->type == aarg_strings) fprintf (stderr, "..."); */ } if (extra_string && *extra_string) printf (".Ar %s\n", extra_string); printf(".Sh DESCRIPTION\n"); printf("Supported options:\n"); printf(".Bl -tag -width Ds\n"); for(arg = args; arg->type; arg++) { if(arg->short_name){ printf(".It Fl %c", arg->short_name); print_arg(stdout, 1, 0, args, style); printf("\n"); } if(arg->long_name){ printf(".It Fl %s%s", style & AARG_TRANSLONG ? "" : "-", arg->long_name); print_arg(stdout, 1, 1, args, style); printf("\n"); } if(arg->help) printf("%s\n", arg->help); /* if(arg->type == aarg_strings) fprintf (stderr, "..."); */ } printf(".El\n"); printf(".\\\".Sh ENVIRONMENT\n"); printf(".\\\".Sh FILES\n"); printf(".\\\".Sh EXAMPLES\n"); printf(".\\\".Sh DIAGNOSTICS\n"); printf(".\\\".Sh SEE ALSO\n"); printf(".\\\".Sh STANDARDS\n"); printf(".\\\".Sh HISTORY\n"); printf(".\\\".Sh AUTHORS\n"); printf(".\\\".Sh BUGS\n"); }
static void mandoc_template(struct getargs *args, size_t num_args, const char *progname, const char *extra_string) { size_t i; char timestr[64], cmd[64]; char buf[128]; const char *p; time_t t; printf(".\\\" Things to fix:\n"); printf(".\\\" * correct section, and operating system\n"); printf(".\\\" * remove Op from mandatory flags\n"); printf(".\\\" * use better macros for arguments (like .Pa for files)\n"); printf(".\\\"\n"); t = time(NULL); strftime(timestr, sizeof(timestr), "%B %e, %Y", localtime(&t)); printf(".Dd %s\n", timestr); p = strrchr(progname, '/'); if(p) p++; else p = progname; strlcpy(cmd, p, sizeof(cmd)); strupr(cmd); printf(".Dt %s SECTION\n", cmd); printf(".Os OPERATING_SYSTEM\n"); printf(".Sh NAME\n"); printf(".Nm %s\n", p); printf(".Nd\n"); printf("in search of a description\n"); printf(".Sh SYNOPSIS\n"); printf(".Nm\n"); for(i = 0; i < num_args; i++){ /* we seem to hit a limit on number of arguments if doing short and long flags with arguments -- split on two lines */ if(ISFLAG(args[i]) || args[i].short_name == 0 || args[i].long_name == NULL) { printf(".Op "); if(args[i].short_name) { print_arg(buf, sizeof(buf), 1, 0, args + i); printf("Fl %c%s", args[i].short_name, buf); if(args[i].long_name) printf(" | "); } if(args[i].long_name) { print_arg(buf, sizeof(buf), 1, 1, args + i); printf("Fl -%s%s%s", args[i].type == arg_negative_flag ? "no-" : "", args[i].long_name, buf); } printf("\n"); } else { print_arg(buf, sizeof(buf), 1, 0, args + i); printf(".Oo Fl %c%s \\*(Ba Xo\n", args[i].short_name, buf); print_arg(buf, sizeof(buf), 1, 1, args + i); printf(".Fl -%s%s Oc\n.Xc\n", args[i].long_name, buf); } /* if(args[i].type == arg_strings) fprintf (stderr, "..."); */ } if (extra_string && *extra_string) printf (".Ar %s\n", extra_string); printf(".Sh DESCRIPTION\n"); printf("Supported options:\n"); printf(".Bl -tag -width Ds\n"); for(i = 0; i < num_args; i++){ printf(".It Xo\n"); if(args[i].short_name){ printf(".Fl %c", args[i].short_name); print_arg(buf, sizeof(buf), 1, 0, args + i); printf("%s", buf); if(args[i].long_name) printf(" Ns ,"); printf("\n"); } if(args[i].long_name){ printf(".Fl -%s%s", args[i].type == arg_negative_flag ? "no-" : "", args[i].long_name); print_arg(buf, sizeof(buf), 1, 1, args + i); printf("%s\n", buf); } printf(".Xc\n"); if(args[i].help) printf("%s\n", args[i].help); /* if(args[i].type == arg_strings) fprintf (stderr, "..."); */ } printf(".El\n"); printf(".\\\".Sh ENVIRONMENT\n"); printf(".\\\".Sh FILES\n"); printf(".\\\".Sh EXAMPLES\n"); printf(".\\\".Sh DIAGNOSTICS\n"); printf(".\\\".Sh SEE ALSO\n"); printf(".\\\".Sh STANDARDS\n"); printf(".\\\".Sh HISTORY\n"); printf(".\\\".Sh AUTHORS\n"); printf(".\\\".Sh BUGS\n"); }
int main(int argc, char **argv) { char *app, *server, *match, *parm, *tmp, *cmd, *extra; int i, j, c, fd; int verbose, result, status, base, run, info, reply, display, max, prefix, timeout, fmt, pos, flags, munge, show; struct katcl_line *l, *k; fd_set fsr, fsw; struct timeval tv; server = getenv("KATCP_SERVER"); if(server == NULL){ server = "localhost"; } info = 1; reply = 1; verbose = 1; i = j = 1; app = argv[0]; base = (-1); timeout = 5; fmt = FMT_TEXT; pos = (-1); k = NULL; munge = 0; show = 1; while (i < argc) { if (argv[i][0] == '-') { c = argv[i][j]; switch (c) { case 'h' : usage(app); return 0; case 'v' : verbose++; j++; break; case 'q' : verbose = 0; info = 0; reply = 0; j++; break; case 'i' : info = 1 - info; j++; break; case 'r' : reply = 1 - reply; j++; break; case 'n' : show = 0; j++; break; case 'k' : k = create_katcl(STDOUT_FILENO); if(k == NULL){ fprintf(stderr, "%s: unable to create katcp message logic\n", app); return 2; } j++; break; case 'a' : fmt = FMT_AUTO; j++; break; case 'x' : fmt = FMT_HEX; j++; break; case 'b' : fmt = FMT_BIN; j++; break; case 'm' : munge = 1; j++; break; case 's' : case 't' : case 'p' : j++; if (argv[i][j] == '\0') { j = 0; i++; } if (i >= argc) { fprintf(stderr, "%s: argument needs a parameter\n", app); return 2; } switch(c){ case 's' : server = argv[i] + j; break; case 't' : timeout = atoi(argv[i] + j); break; case 'p' : pos = atoi(argv[i] + j); if(pos < 0){ fprintf(stderr, "%s: position needs to be nonnegative, not %d\n", app, pos); return 2; } break; } i++; j = 1; break; case '-' : j++; break; case '\0': j = 1; i++; break; default: fprintf(stderr, "%s: unknown option -%c\n", app, argv[i][j]); return 2; } } else { base = i; i = argc; } } if(munge){ if(k){ reply = 1; } } if(base < 0){ if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCMD_NAME, "no command given"); } fprintf(stderr, "%s: need a command to send (use -h for help)\n", app); return 2; } status = 1; flags = 0; if(verbose > 0){ flags = NETC_VERBOSE_ERRORS; if(verbose > 1){ flags = NETC_VERBOSE_STATS; } } fd = net_connect(server, 0, flags); if(fd < 0){ if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCMD_NAME, "unable to connect to %s", server); } return 2; } l = create_katcl(fd); if(l == NULL){ if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCMD_NAME, "unable to create katcp parser"); } fprintf(stderr, "%s: unable to create katcp parser\n", app); return 2; } i = base; match = NULL; flags = ((i + 1) < argc) ? KATCP_FLAG_FIRST : (KATCP_FLAG_FIRST | KATCP_FLAG_LAST); switch(argv[i][0]){ case KATCP_REQUEST : match = argv[i] + 1; /* FALL */ case KATCP_INFORM : case KATCP_REPLY : append_string_katcl(l, flags, argv[i]); break; default : match = argv[i]; append_args_katcl(l, flags, "%c%s", KATCP_REQUEST, argv[i]); break; } i++; while(i < argc){ tmp = argv[i]; i++; flags = (i < argc) ? 0 : KATCP_FLAG_LAST; if(load_arg(l, tmp, fmt, flags) < 0){ if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCMD_NAME, "unable to load argument %d", i); } fprintf(stderr, "%s: unable to load argument %d\n", app, i); return 2; } } if(match){ for(prefix = 0; (match[prefix] != '\0') && (match[prefix] != ' '); prefix++); #ifdef DEBUG fprintf(stderr, "debug: checking prefix %d of %s\n", prefix, match); #endif } else { prefix = 0; /* pacify -Wall, prefix only used if match is set */ } /* WARNING: logic a bit intricate */ for(run = 1; run;){ FD_ZERO(&fsr); FD_ZERO(&fsw); if(match){ /* only look for data if we need it */ FD_SET(fd, &fsr); } if(flushing_katcl(l)){ /* only write data if we have some */ FD_SET(fd, &fsw); } tv.tv_sec = timeout; tv.tv_usec = 0; result = select(fd + 1, &fsr, &fsw, NULL, &tv); switch(result){ case -1 : switch(errno){ case EAGAIN : case EINTR : continue; /* WARNING */ default : if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCMD_NAME, "select failed: %s", strerror(errno)); } return 2; } break; case 0 : if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCMD_NAME, "request timed out after %d seconds", timeout); } if(verbose){ fprintf(stderr, "%s: no io activity within %d seconds\n", app, timeout); } /* could terminate cleanly here, but ... */ return 2; } if(FD_ISSET(fd, &fsw)){ result = write_katcl(l); if(result < 0){ if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCMD_NAME, "write failed: %s", strerror(errno)); } fprintf(stderr, "%s: write failed: %s\n", app, strerror(error_katcl(l))); return 2; } if((result > 0) && (match == NULL)){ /* if we finished writing and don't expect a match then quit */ run = 0; } } if(FD_ISSET(fd, &fsr)){ result = read_katcl(l); if(result){ if(k){ sync_message_katcl(k, KATCP_LEVEL_ERROR, KCPCMD_NAME, "read failed: %s", (result < 0) ? strerror(error_katcl(l)) : "connection terminated"); } fprintf(stderr, "%s: read failed: %s\n", app, (result < 0) ? strerror(error_katcl(l)) : "connection terminated"); return 2; } } while(have_katcl(l) > 0){ cmd = arg_string_katcl(l, 0); if(cmd){ display = 0; switch(cmd[0]){ case KATCP_INFORM : display = info; if(show == 0){ if(!strcmp(KATCP_VERSION_CONNECT_INFORM, cmd)){ display = 0; } } break; case KATCP_REPLY : display = reply; parm = arg_string_katcl(l, 1); if(match){ if(strncmp(match, cmd + 1, prefix) || ((cmd[prefix + 1] != '\0') && (cmd[prefix + 1] != ' '))){ if(k){ sync_message_katcl(k, KATCP_LEVEL_WARN, KCPCMD_NAME, "encountered unexpected reply %s", cmd); } fprintf(stderr, "%s: warning: encountered unexpected reply <%s>\n", app, cmd); } else { if(parm && !strcmp(parm, KATCP_OK)){ status = 0; } run = 0; } } break; case KATCP_REQUEST : if(k){ sync_message_katcl(k, KATCP_LEVEL_WARN, KCPCMD_NAME, "encountered unanswerable request %s", cmd); } fprintf(stderr, "%s: warning: encountered an unanswerable request <%s>\n", app, cmd); break; default : if(k){ sync_message_katcl(k, KATCP_LEVEL_WARN, KCPCMD_NAME, "read malformed message %s", cmd); } fprintf(stderr, "%s: read malformed message <%s>\n", app, cmd); break; } if(display){ #ifdef DEBUG fprintf(stderr, "need to display\n"); #endif if(k){ if(munge && parm && (cmd[0] == KATCP_REPLY)){ if(!strcmp(parm, KATCP_OK)){ sync_message_katcl(k, KATCP_LEVEL_DEBUG, cmd + 1, KATCP_OK); } else { extra = arg_string_katcl(l, 2); sync_message_katcl(k, KATCP_LEVEL_WARN, cmd + 1, "%s (%s)", parm, extra ? extra : "no extra information"); } } else { relay_katcl(l, k); } } else { max = arg_count_katcl(l); if(pos < 0){ for(i = 0; i < max; i++){ if(print_arg(l, i, fmt) < 0){ fprintf(stderr, "%s: failed to print argument %d\n", app, i); return 2; } fputc(((i + 1) == max) ? '\n' : ' ' , stdout); } } else { if(pos < max){ i = pos; if(print_arg(l, i, fmt) < 0){ fprintf(stderr, "%s: failed to print argument %d\n", app, i); return 2; } } } } } } } } destroy_katcl(l, 1); if(k){ while(write_katcl(k) == 0); destroy_katcl(k, 0); } return status; }
void aarg_printusage (struct agetargs *args, const char *progname, const char *extra_string, int style) { struct agetargs *arg; size_t max_len = 0; if (progname == NULL) progname = __progname; if(getenv("GETARGMANDOC")){ mandoc_template(args, extra_string, style); return; } fprintf (stderr, "Usage: %s", progname); for (arg = args; arg->type; arg++) { size_t len = 0; if (arg->long_name) { if (style & AARG_TRANSLONG) { switch (arg->mandatoryp) { case aarg_mandatory: fprintf (stderr, " -"); break; default: fprintf (stderr, " [-"); break; } } else fprintf (stderr, " [--"); if (arg->type == aarg_negative_flag) { fprintf (stderr, "no-"); len += 3; } fprintf (stderr, "%s", arg->long_name); len += 2 + strlen(arg->long_name); len += print_arg (stderr, 0, 1, arg, style); if(arg->type == aarg_strings) fprintf (stderr, "..."); if(!(style & AARG_TRANSLONG) || arg->mandatoryp != aarg_mandatory) putc (']', stderr); } if (arg->short_name) { len += 2; fprintf (stderr, " [-%c", arg->short_name); len += print_arg (stderr, 0, 0, arg, style); putc (']', stderr); if(arg->type == aarg_strings) fprintf (stderr, "..."); } if (arg->long_name && arg->short_name) len += 4; max_len = max(max_len, len); } if (extra_string) fprintf (stderr, " %s\n", extra_string); else fprintf (stderr, "\n"); for (arg = args; arg->type; arg++) { if (arg->help) { size_t count = 0; if (arg->short_name) { fprintf (stderr, "-%c", arg->short_name); count += 2; count += print_arg (stderr, 0, 0, arg, style); } if (arg->short_name && arg->long_name) { fprintf (stderr, " or "); count += 4; } if (arg->long_name) { fprintf (stderr, "-%s", style & AARG_TRANSLONG ? "" : "-"); if (arg->type == aarg_negative_flag) { fprintf (stderr, "no-"); count += 3; } fprintf (stderr, "%s", arg->long_name); count += 2 + strlen(arg->long_name); count += print_arg (stderr, 0, 1, arg, style); } while(count++ <= max_len) putc (' ', stderr); fprintf (stderr, "%s\n", arg->help); } } }
void amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs) { struct reg regs; int syscall_num; int i; struct syscall *sc; cpid = trussinfo->curthread->tid; clear_fsc(); if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } syscall_num = regs.r_rax; fsc.number = syscall_num; fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : linux32_syscallnames[syscall_num]; if (!fsc.name) { fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); } if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && ((!strcmp(fsc.name, "linux_fork") || !strcmp(fsc.name, "linux_vfork")))) { trussinfo->curthread->in_fork = 1; } if (nargs == 0) return; /* * Linux passes syscall arguments in registers, not * on the stack. Fortunately, we've got access to the * register set. Note that we don't bother checking the * number of arguments. And what does linux do for syscalls * that have more than five arguments? */ fsc.args[0] = regs.r_rbx; fsc.args[1] = regs.r_rcx; fsc.args[2] = regs.r_rdx; fsc.args[3] = regs.r_rsi; fsc.args[4] = regs.r_rdi; sc = get_syscall(fsc.name); if (sc) { fsc.nargs = sc->nargs; } else { #if DEBUG fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", fsc.name, nargs); #endif fsc.nargs = nargs; } fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* * At this point, we set up the system call arguments. * We ignore any OUT ones, however -- those are arguments that * are set by the system call, and so are probably meaningless * now. This doesn't currently support arguments that are * passed in *and* out, however. */ if (fsc.name) { #if DEBUG fprintf(stderr, "syscall %s(", fsc.name); #endif for (i = 0; i < fsc.nargs; i++) { #if DEBUG fprintf(stderr, "0x%x%s", sc ? fsc.args[sc->args[i].offset] : fsc.args[i], i < (fsc.nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); } } #if DEBUG fprintf(stderr, ")\n"); #endif } #if DEBUG fprintf(trussinfo->outfile, "\n"); #endif if (fsc.name != NULL && (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) { /* XXX * This could be done in a more general * manner but it still wouldn't be very pretty. */ if (!strcmp(fsc.name, "linux_execve")) { if ((trussinfo->flags & EXECVEARGS) == 0) if (fsc.s_args[1]) { free(fsc.s_args[1]); fsc.s_args[1] = NULL; } if ((trussinfo->flags & EXECVEENVS) == 0) if (fsc.s_args[2]) { free(fsc.s_args[2]); fsc.s_args[2] = NULL; } } } return; }
long amd64_linux32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { struct reg regs; long retval; int i; int errorp; struct syscall *sc; if (fsc.name == NULL) return (-1); cpid = trussinfo->curthread->tid; if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return (-1); } retval = regs.r_rax; errorp = !!(regs.r_rflags & PSL_C); /* * This code, while simpler than the initial versions I used, could * stand some significant cleaning. */ sc = fsc.sc; if (!sc) { for (i = 0; i < fsc.nargs; i++) asprintf(&fsc.s_args[i], "0x%lx", fsc.args[i]); } else { /* * Here, we only look for arguments that have OUT masked in -- * otherwise, they were handled in the syscall_entry function. */ for (i = 0; i < sc->nargs; i++) { char *temp; if (sc->args[i].type & OUT) { /* * If an error occurred, than don't bothe getting the data; * it may not be valid. */ if (errorp) asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]); else temp = print_arg(&sc->args[i], fsc.args, retval, trussinfo); fsc.s_args[i] = temp; } } } /* * It would probably be a good idea to merge the error handling, * but that complicates things considerably. */ if (errorp) { for (i = 0; (size_t)i < sizeof(bsd_to_linux_errno) / sizeof(int); i++) if (retval == bsd_to_linux_errno[i]) break; } if (fsc.name != NULL && (!strcmp(fsc.name, "linux_execve") || !strcmp(fsc.name, "exit"))) { trussinfo->curthread->in_syscall = 1; } print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, errorp ? i : retval, fsc.sc); clear_fsc(); return (retval); }
void ROKEN_LIB_FUNCTION arg_printusage_i18n (struct getargs *args, size_t num_args, const char *usage, const char *progname, const char *extra_string, char *(i18n)(const char *)) { int i; size_t max_len = 0; char buf[128]; int col = 0, columns; struct winsize ws; if (progname == NULL) progname = getprogname(); if (i18n == NULL) i18n = builtin_i18n; if(getenv("GETARGMANDOC")){ mandoc_template(args, num_args, progname, extra_string, i18n); return; } if(get_window_size(2, &ws) == 0) columns = ws.ws_col; else columns = 80; col = 0; col += fprintf (stderr, "%s: %s", usage, progname); buf[0] = '\0'; for (i = 0; i < num_args; ++i) { if(args[i].short_name && ISFLAG(args[i])) { char s[2]; if(buf[0] == '\0') strlcpy(buf, "[-", sizeof(buf)); s[0] = args[i].short_name; s[1] = '\0'; strlcat(buf, s, sizeof(buf)); } } if(buf[0] != '\0') { strlcat(buf, "]", sizeof(buf)); col = check_column(stderr, col, strlen(buf) + 1, columns); col += fprintf(stderr, " %s", buf); } for (i = 0; i < num_args; ++i) { size_t len = 0; if (args[i].long_name) { buf[0] = '\0'; strlcat(buf, "[--", sizeof(buf)); len += 2; if(args[i].type == arg_negative_flag) { strlcat(buf, "no-", sizeof(buf)); len += 3; } strlcat(buf, args[i].long_name, sizeof(buf)); len += strlen(args[i].long_name); len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 0, 1, &args[i], i18n); strlcat(buf, "]", sizeof(buf)); if(args[i].type == arg_strings) strlcat(buf, "...", sizeof(buf)); col = check_column(stderr, col, strlen(buf) + 1, columns); col += fprintf(stderr, " %s", buf); } if (args[i].short_name && !ISFLAG(args[i])) { snprintf(buf, sizeof(buf), "[-%c", args[i].short_name); len += 2; len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 0, 0, &args[i], i18n); strlcat(buf, "]", sizeof(buf)); if(args[i].type == arg_strings) strlcat(buf, "...", sizeof(buf)); col = check_column(stderr, col, strlen(buf) + 1, columns); col += fprintf(stderr, " %s", buf); } if (args[i].long_name && args[i].short_name) len += 2; /* ", " */ max_len = max(max_len, len); } if (extra_string) { check_column(stderr, col, strlen(extra_string) + 1, columns); fprintf (stderr, " %s\n", extra_string); } else fprintf (stderr, "\n"); for (i = 0; i < num_args; ++i) { if (args[i].help) { size_t count = 0; if (args[i].short_name) { count += fprintf (stderr, "-%c", args[i].short_name); print_arg (buf, sizeof(buf), 0, 0, &args[i], i18n); count += fprintf(stderr, "%s", buf); } if (args[i].short_name && args[i].long_name) count += fprintf (stderr, ", "); if (args[i].long_name) { count += fprintf (stderr, "--"); if (args[i].type == arg_negative_flag) count += fprintf (stderr, "no-"); count += fprintf (stderr, "%s", args[i].long_name); print_arg (buf, sizeof(buf), 0, 1, &args[i], i18n); count += fprintf(stderr, "%s", buf); } while(count++ <= max_len) putc (' ', stderr); fprintf (stderr, "%s\n", (*i18n)(args[i].help)); } } }
void arm_syscall_entry(struct trussinfo *trussinfo, int nargs) { struct ptrace_io_desc iorequest; struct reg regs; struct freebsd_syscall *fsc; struct syscall *sc; lwpid_t tid; int i, syscall_num; register_t *ap; tid = trussinfo->curthread->tid; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } ap = ®s.r[0]; /* * FreeBSD has two special kinds of system call redirctions -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. */ #ifdef __ARM_EABI__ syscall_num = regs.r[7]; #else if ((syscall_num = ptrace(PT_READ_I, tid, (caddr_t)(regs.r[_REG_PC] - INSN_SIZE), 0)) == -1) { fprintf(trussinfo->outfile, "-- CANNOT READ PC --\n"); return; } syscall_num = syscall_num & 0x000fffff; #endif switch (syscall_num) { case SYS_syscall: syscall_num = *ap++; nargs--; break; case SYS___syscall: syscall_num = ap[_QUAD_LOWWORD]; ap += 2; nargs -= 2; break; } fsc = alloc_fsc(); if (fsc == NULL) return; fsc->number = syscall_num; fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; if (!fsc->name) { fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); } if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && (strcmp(fsc->name, "fork") == 0 || strcmp(fsc->name, "rfork") == 0 || strcmp(fsc->name, "vfork") == 0)) trussinfo->curthread->in_fork = 1; if (nargs == 0) return; fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); switch (nargs) { default: /* * The OS doesn't seem to allow more than 10 words of * parameters (yay!). So we shouldn't be here. */ warn("More than 10 words (%d) of arguments!\n", nargs); break; case 10: case 9: case 8: case 7: case 6: case 5: /* * If there are 7-10 words of arguments, they are placed * on the stack, as is normal for other processors. * The fall-through for all of these is deliberate!!! */ // XXX BAD constant used here iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)(regs.r[_REG_SP] + 4 * sizeof(uint32_t)); iorequest.piod_addr = &fsc->args[4]; iorequest.piod_len = (nargs - 4) * sizeof(fsc->args[0]); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) return; case 4: fsc->args[3] = ap[3]; case 3: fsc->args[2] = ap[2]; case 2: fsc->args[1] = ap[1]; case 1: fsc->args[0] = ap[0]; case 0: break; } sc = NULL; if (fsc->name) sc = get_syscall(fsc->name); if (sc) fsc->nargs = sc->nargs; else { #if DEBUG fprintf(trussinfo->outfile, "unknown syscall %s -- setting " "args to %d\n", fsc->name, nargs); #endif fsc->nargs = nargs; } fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); fsc->sc = sc; /* * At this point, we set up the system call arguments. * We ignore any OUT ones, however -- those are arguments that * are set by the system call, and so are probably meaningless * now. This doesn't currently support arguments that are * passed in *and* out, however. */ if (fsc->name) { #if DEBUG fprintf(stderr, "syscall %s(", fsc->name); #endif for (i = 0; i < fsc->nargs; i++) { #if DEBUG fprintf(stderr, "0x%x%s", sc ? fsc->args[sc->args[i].offset] : fsc->args[i], i < (fsc->nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { fsc->s_args[i] = print_arg(&sc->args[i], fsc->args, 0, trussinfo); } } #if DEBUG fprintf(stderr, ")\n"); #endif } #if DEBUG fprintf(trussinfo->outfile, "\n"); #endif if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || strcmp(fsc->name, "exit") == 0)) { /* * XXX * This could be done in a more general * manner but it still wouldn't be very pretty. */ if (strcmp(fsc->name, "execve") == 0) { if ((trussinfo->flags & EXECVEARGS) == 0) { if (fsc->s_args[1]) { free(fsc->s_args[1]); fsc->s_args[1] = NULL; } } if ((trussinfo->flags & EXECVEENVS) == 0) { if (fsc->s_args[2]) { free(fsc->s_args[2]); fsc->s_args[2] = NULL; } } } } trussinfo->curthread->fsc = fsc; }
int main(int argc, char** argv, char** environ) { typeThree test; typeThree* t2; int i; int p=0; /* Number of processors */ int source; /* Rank of sender */ int dest; /* Rank of receiver */ int tag = 50; /* Tag for messages */ char message[100]; /* Storage for the message */ int my_rank; /* Rank of process */ float tables[12][12]; const char* troopa; int bigArray[10000]; int x,y; int beingWatched; int* sdim; int* dynamicArray; void (*s)(int); MPI_Status status; /* Return status for receive */ t2 = malloc(sizeof(typeThree)); for(p=0;p<100;p++) bigArray[p]=80000+p; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &p); dynamicArray = malloc(sizeof(int)*100000); sdim = malloc(sizeof(int) * p); for(x=0;x<10000;x++) { dynamicArray[x] = x%10; } printf("my rank is %d\n", my_rank); for(x=0;x<12;x++) { y = 0; while(y != 12) { tables[x][y] = (x+1)*(y+1); y += my_rank + 1; } } if(argc > 1 && my_rank == 0) { printf("Rank %d has %d arguments.\n", my_rank, argc); printf("They are:\n"); for(x=0; x<argc; y++) print_arg(argv[y]); } func1(); func2(); fprintf(stderr, "I can write to stderr too\n"); beingWatched = 1; test.anotherList.subList.charStar = "hello"; test.c = 'p'; beingWatched = 0; /* while (-1) { } */ for(x=0; x<p; x++) sdim[x] = my_rank * x; if (my_rank != 0) { sprintf(message, "Greetings from process %d!", my_rank); printf("sending message from (%d)\n",my_rank); dest = 0; /* Use strlen(message)+1 to include '\0' */ MPI_Send(message, strlen(message)+1, MPI_CHAR, dest, tag, MPI_COMM_WORLD); beingWatched--; } else { /* my_rank == 0 */ for (source = 1; source < p; source++) { printf("waiting for message from (%d)\n", source); MPI_Recv(message, 100, MPI_CHAR, source, tag, MPI_COMM_WORLD, &status); printf("%s\n", message); beingWatched++; } } for(i=1;i<argc;i++) if (argv[i] && !strcmp(argv[i], "memcrash")) func3(); for(i=1;i<argc;i++) if (argv[i] && !strcmp(argv[i], "sleepy")) sleep(500000); beingWatched = 12; MPI_Finalize(); beingWatched = 0; printf("all done...(%d)\n",my_rank); return 0; } /* main */
void i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { struct reg regs; int syscall_num; int i; unsigned int parm_offset; struct syscall *sc = NULL; struct ptrace_io_desc iorequest; cpid = trussinfo->curthread->tid; clear_fsc(); if (ptrace(PT_GETREGS, cpid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } parm_offset = regs.r_esp + sizeof(int); /* * FreeBSD has two special kinds of system call redirctions -- * SYS_syscall, and SYS___syscall. The former is the old syscall() * routine, basically; the latter is for quad-aligned arguments. */ syscall_num = regs.r_eax; switch (syscall_num) { case SYS_syscall: syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); parm_offset += sizeof(int); break; case SYS___syscall: syscall_num = ptrace(PT_READ_D, cpid, (caddr_t)parm_offset, 0); parm_offset += sizeof(quad_t); break; } fsc.number = syscall_num; fsc.name = (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; if (!fsc.name) { fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); } if (fsc.name && (trussinfo->flags & FOLLOWFORKS) && ((!strcmp(fsc.name, "fork") || !strcmp(fsc.name, "rfork") || !strcmp(fsc.name, "vfork")))) { trussinfo->curthread->in_fork = 1; } if (nargs == 0) return; fsc.args = malloc((1+nargs) * sizeof(unsigned long)); iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)parm_offset; iorequest.piod_addr = fsc.args; iorequest.piod_len = (1+nargs) * sizeof(unsigned long); ptrace(PT_IO, cpid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) return; if (fsc.name) sc = get_syscall(fsc.name); if (sc) { fsc.nargs = sc->nargs; } else { #if DEBUG fprintf(trussinfo->outfile, "unknown syscall %s -- setting args to %d\n", fsc.name, nargs); #endif fsc.nargs = nargs; } fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* * At this point, we set up the system call arguments. * We ignore any OUT ones, however -- those are arguments that * are set by the system call, and so are probably meaningless * now. This doesn't currently support arguments that are * passed in *and* out, however. */ if (fsc.name) { #if DEBUG fprintf(stderr, "syscall %s(", fsc.name); #endif for (i = 0; i < fsc.nargs; i++) { #if DEBUG fprintf(stderr, "0x%x%s", sc ? fsc.args[sc->args[i].offset] : fsc.args[i], i < (fsc.nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { fsc.s_args[i] = print_arg(&sc->args[i], fsc.args, 0, trussinfo); } } #if DEBUG fprintf(stderr, ")\n"); #endif } #if DEBUG fprintf(trussinfo->outfile, "\n"); #endif if (fsc.name != NULL && (!strcmp(fsc.name, "execve") || !strcmp(fsc.name, "exit"))) { /* XXX * This could be done in a more general * manner but it still wouldn't be very pretty. */ if (!strcmp(fsc.name, "execve")) { if ((trussinfo->flags & EXECVEARGS) == 0) if (fsc.s_args[1]) { free(fsc.s_args[1]); fsc.s_args[1] = NULL; } if ((trussinfo->flags & EXECVEENVS) == 0) if (fsc.s_args[2]) { free(fsc.s_args[2]); fsc.s_args[2] = NULL; } } } return; }
void mips_syscall_entry(struct trussinfo *trussinfo, int nargs) { struct ptrace_io_desc iorequest; struct reg regs; struct freebsd_syscall *fsc; struct syscall *sc; lwpid_t tid; int i, syscall_num; int indir; /* indirect system call */ tid = trussinfo->curthread->tid; if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); return; } indir = 0; syscall_num = regs.r_regs[V0]; if (syscall_num == SYS_syscall) { indir = 1; syscall_num = regs.r_regs[A0]; } fsc = alloc_fsc(); if (fsc == NULL) return; fsc->number = syscall_num; fsc->name = (syscall_num < 0 || syscall_num >= nsyscalls) ? NULL : syscallnames[syscall_num]; if (!fsc->name) { fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num); } if (fsc->name && (trussinfo->flags & FOLLOWFORKS) && (strcmp(fsc->name, "fork") == 0 || strcmp(fsc->name, "rfork") == 0 || strcmp(fsc->name, "vfork") == 0)) trussinfo->curthread->in_fork = 1; if (nargs == 0) return; fsc->args = malloc((1 + nargs) * sizeof(unsigned long)); #if 0 // XXX iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)parm_offset; iorequest.piod_addr = fsc->args; iorequest.piod_len = (1 + nargs) * sizeof(unsigned long); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) return; #else iorequest.piod_op = PIOD_READ_D; #endif switch (nargs) { default: /* * The OS doesn't seem to allow more than 10 words of * parameters (yay!). So we shouldn't be here. */ warn("More than 10 words (%d) of arguments!\n", nargs); break; case 10: case 9: case 8: case 7: case 6: case 5: /* * If there are 7-10 words of arguments, they are placed * on the stack, as is normal for other processors. * The fall-through for all of these is deliberate!!! */ // XXX BAD constant used here iorequest.piod_op = PIOD_READ_D; iorequest.piod_offs = (void *)(regs.r_regs[SP] + 4 * sizeof(uint32_t)); iorequest.piod_addr = &fsc->args[4]; iorequest.piod_len = (nargs - 4) * sizeof(fsc->args[0]); ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); if (iorequest.piod_len == 0) return; case 4: fsc->args[3] = regs.r_regs[A3]; case 3: fsc->args[2] = regs.r_regs[A2]; case 2: fsc->args[1] = regs.r_regs[A1]; case 1: fsc->args[0] = regs.r_regs[A0]; case 0: break; } if (indir) { memmove(&fsc->args[0], &fsc->args[1], (nargs - 1) * sizeof(fsc->args[0])); } sc = get_syscall(fsc->name); if (sc) fsc->nargs = sc->nargs; else { #if DEBUG fprintf(trussinfo->outfile, "unknown syscall %s -- setting " "args to %d\n", fsc->name, nargs); #endif fsc->nargs = nargs; } fsc->s_args = calloc(1, (1 + fsc->nargs) * sizeof(char *)); fsc->sc = sc; /* * At this point, we set up the system call arguments. * We ignore any OUT ones, however -- those are arguments that * are set by the system call, and so are probably meaningless * now. This doesn't currently support arguments that are * passed in *and* out, however. */ if (fsc->name) { #if DEBUG fprintf(stderr, "syscall %s(", fsc->name); #endif for (i = 0; i < fsc->nargs; i++) { #if DEBUG fprintf(stderr, "0x%x%s", sc ? fsc->args[sc->args[i].offset] : fsc->args[i], i < (fsc->nargs - 1) ? "," : ""); #endif if (sc && !(sc->args[i].type & OUT)) { fsc->s_args[i] = print_arg(&sc->args[i], fsc->args, 0, trussinfo); } } #if DEBUG fprintf(stderr, ")\n"); #endif } #if DEBUG fprintf(trussinfo->outfile, "\n"); #endif if (fsc->name != NULL && (strcmp(fsc->name, "execve") == 0 || strcmp(fsc->name, "exit") == 0)) { /* * XXX * This could be done in a more general * manner but it still wouldn't be very pretty. */ if (strcmp(fsc->name, "execve") == 0) { if ((trussinfo->flags & EXECVEARGS) == 0) { if (fsc->s_args[1]) { free(fsc->s_args[1]); fsc->s_args[1] = NULL; } } if ((trussinfo->flags & EXECVEENVS) == 0) { if (fsc->s_args[2]) { free(fsc->s_args[2]); fsc->s_args[2] = NULL; } } } } trussinfo->curthread->fsc = fsc; }
void arg_printusage (struct getargs *args, size_t num_args, const char *progname, const char *extra_string) { int i; size_t max_len = 0; char buf[128]; int col = 0, columns; struct winsize ws; columns = 80; col = 0; col += fprintf (stderr, "Usage: %s", progname); for (i = 0; i < num_args; ++i) { size_t len = 0; if (args[i].long_name) { buf[0] = '\0'; strncat(buf, "[--", sizeof(buf)); len += 2; if(args[i].type == arg_negative_flag) { strncat(buf, "no-", sizeof(buf)); len += 3; } strncat(buf, args[i].long_name, sizeof(buf)); len += strlen(args[i].long_name); len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 0, 1, &args[i]); strncat(buf, "]", sizeof(buf)); if(args[i].type == arg_strings) strncat(buf, "...", sizeof(buf)); col = check_column(stderr, col, strlen(buf) + 1, columns); col += fprintf(stderr, " %s", buf); } if (args[i].short_name) { snprintf(buf, sizeof(buf), "[-%c", args[i].short_name); len += 2; len += print_arg(buf + strlen(buf), sizeof(buf) - strlen(buf), 0, 0, &args[i]); strncat(buf, "]", sizeof(buf)); if(args[i].type == arg_strings) strncat(buf, "...", sizeof(buf)); col = check_column(stderr, col, strlen(buf) + 1, columns); col += fprintf(stderr, " %s", buf); } if (args[i].long_name && args[i].short_name) len += 2; /* ", " */ max_len = max(max_len, len); } if (extra_string) { col = check_column(stderr, col, strlen(extra_string) + 1, columns); fprintf (stderr, " %s\n", extra_string); } else fprintf (stderr, "\n"); for (i = 0; i < num_args; ++i) { if (args[i].help) { size_t count = 0; if (args[i].short_name) { count += fprintf (stderr, "-%c", args[i].short_name); print_arg (buf, sizeof(buf), 0, 0, &args[i]); count += fprintf(stderr, "%s", buf); } if (args[i].short_name && args[i].long_name) count += fprintf (stderr, ", "); if (args[i].long_name) { count += fprintf (stderr, "--"); if (args[i].type == arg_negative_flag) count += fprintf (stderr, "no-"); count += fprintf (stderr, "%s", args[i].long_name); print_arg (buf, sizeof(buf), 0, 1, &args[i]); count += fprintf(stderr, "%s", buf); } while(count++ <= max_len) putc (' ', stderr); fprintf (stderr, "%s\n", args[i].help); } } }
void print1(int a, int b, int c) { print_arg(a, b, c); }