Newsgroups: comp.sources.unix From: bruce@beta.cs.su.oz.au (Bruce Janson) Subject: v25i160: trash - simulate process execution in MIPS RISC/os 4.52, Part06/08 Sender: unix-sources-moderator@pa.dec.com Approved: vixie@pa.dec.com Submitted-By: bruce@beta.cs.su.oz.au (Bruce Janson) Posting-Number: Volume 25, Issue 160 Archive-Name: trash/part06 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'i_syscall.c' <<'END_OF_FILE' X#include X#include X#include X#include X#include X#include X#include X#include X#define INKERNEL 1 X#include X#undef INKERNEL X#include X#include X#include X#include X#include "register.h" X#include "symtab.h" X#include "diblock.h" X#include "instrn.h" X#include "process.h" X#include "sysentry.h" X#include "res.h" X#include "nels.h" X X#define TRUNCATED_READ_WRITE_LENGTH 32 X Xextern char *malloc(); Xextern char *realloc(); Xextern char *ctime(); Xextern char *sysmess(); Xextern sysentry *sysv_systab_entry(); Xextern sysentry *bsd43_systab_entry(); Xextern sysentry *posix_systab_entry(); X Xextern int sysv_print_open_flags(); Xextern int bsd43_print_open_flags(); Xextern int posix_print_open_flags(); X Xextern int sysv_print_open_mode(); Xextern int bsd43_print_open_mode(); Xextern int posix_print_open_mode(); X Xextern int sysv_print_stat(); Xextern int bsd43_print_stat(); Xextern int posix_print_stat(); X Xextern int sysv_print_ioctl_cmd(); Xextern int bsd43_print_ioctl_cmd(); Xextern int posix_print_ioctl_cmd(); X Xextern int sysv_print_ioctl_arg(); Xextern int bsd43_print_ioctl_arg(); Xextern int posix_print_ioctl_arg(); X Xextern int sysv_print_fdset(); Xextern int bsd43_print_fdset(); Xextern int posix_print_fdset(); X Xextern int sysv_print_whence(); Xextern int bsd43_print_whence(); Xextern int posix_print_whence(); X Xextern int sysv_print_statfs(); Xextern int bsd43_print_statfs(); Xextern int posix_print_statfs(); X Xextern int sysv_print_sigcontext(); Xextern int bsd43_print_sigcontext(); Xextern int posix_print_sigcontext(); X Xextern int bsd43_print_sigvec(); Xextern int sysv_print_wait3_union_wait(); Xextern int sysv_print_wait3_options(); Xextern int sysv_print_wait3_rusage(); X Xextern int Aflag; Xextern int Iflag; Xextern int Nflag; Xextern int Pflag; Xextern int Sflag; Xextern int Tflag; X Xextern char *sys_errnolist[]; Xextern int sys_nerrno; Xextern FILE *outfp; Xextern int errno; Xextern unsigned long instruction_count; Xextern unsigned long instruction_count_since_last_syscall; X Xunsigned long arg[NSYSARGS]; /* Arguments */ X Xdinstrn *GLOBALdipc; Xint return_errno; /* errno goes here. */ Xlong return_value0; /* Result 1 value goes here. */ Xlong return_value1; /* Result 2 value goes here. */ X Xsysentry *current_sysentp; Xchar *sys_call_buf; /* Scratch buf. */ Xunsigned int sys_call_bufz; /* Current size of above. */ X Xint need_leading_pipe; X X/* X * Ensure that the scratch buffer (pointed to by 'sys_call_buf') X * is at least 'n' bytes long. X * Return -1 on error. X */ Xint Xbufset(n) Xunsigned int n; X{ X if (sys_call_bufz >= n) X return 0; X X if (sys_call_bufz == 0) X sys_call_buf = malloc(n); X else X sys_call_buf = realloc(sys_call_buf, n); X X if (sys_call_buf == (char *)0) X { X vcouldnot("expand syscall buffer to %d bytes", n); X return -1; X } X X sys_call_bufz = n; X X return 0; X} X X/* X * Return the length of the string that starts X * at address 'addr' in user memory (like strlen()). X * Return -1 on error. X */ Xint Xmstrlen(addr) Xunsigned long addr; X{ X int length; X char c; X X length = 0; X X for (;;) X { X if (quiet_procmget(GLOBALdipc, addr, &c, sizeof(c)) == -1) X return -1; X X if (c == '\0') X break; X X length++; X addr++; X } X X return length; X} X Xint Xmgetstring(p) Xlong p; X{ X int length; X X if ((length = mstrlen(p)) == -1) X return -1; X X length++; X X if (bufset((unsigned int)length) == -1) X return -1; X X if (quiet_procmget(GLOBALdipc, (unsigned long)p, sys_call_buf, length) == -1) X return -1; X X return length; X} X Xint Xmgets(addr, pp) Xunsigned long addr; Xchar **pp; X{ X int length; X X if (addr == (unsigned long)0) X { X *pp = (char *)0; X return 0; X } X X if ((length = mstrlen(addr)) == -1) X return -1; X X length++; X X if (bufset((unsigned int)length) == -1) X return -1; X X if (quiet_procmget(GLOBALdipc, addr, sys_call_buf, length) == -1) X return -1; X X *pp = sys_call_buf; X X return length; X} X Xint Xmputstring(p) Xlong p; X{ X int length; X X length = strlen(sys_call_buf); X X length++; X X if (quiet_procmput(GLOBALdipc, (unsigned long)p, sys_call_buf, length) == -1) X return -1; X X return length; X} X Xchar ** Xmgetvp(addr) Xunsigned long addr; X{ X int nargs; X int nchars; X char **result; X unsigned long saved_addr; X char **pp; X char *stringp; X X saved_addr = addr; X nargs = 0; X nchars = 0; X X for (;;) X { X char *p; X int length; X X if (quiet_procmget(GLOBALdipc, addr, &p, sizeof(p)) == -1) X return (char **)0; X X if (p == (char *)0) X break; X X if ((length = mstrlen(p)) == -1) X return (char **)0; X X nargs++; X nchars += (length + 1); X addr += sizeof(p); X } X X nargs++; X X addr = saved_addr; X X if ((result = (char **)malloc(sizeof(char *) * nargs + nchars)) == (char **)0) X { X vcouldnot("allocate %d bytes during execve arg processing", sizeof(char *) * nargs + nchars); X return (char **)0; X } X X pp = result; X stringp = (char *)(result + nargs); X X for (;;) X { X char *p; X int length; X X if (quiet_procmget(GLOBALdipc, addr, &p, sizeof(p)) == -1) X return (char **)0; X X if (p == (char *)0) X break; X X if (mgetstring(p) == -1) X return (char **)0; X X *pp++ = stringp; X X (void)strcpy(stringp, sys_call_buf); X stringp += (strlen(sys_call_buf) + 1); X X addr += sizeof(p); X } X X *pp = (char *)0; X X return result; X} X Xint Xmfreevp(p) Xchar **p; X{ X char **cpp; X X for (cpp = p; *cpp != (char *)0; cpp++) X (void)free(*cpp); X X (void)free((char *)cpp); X X return 0; X} X Xint Xdmget(addr, n, pp) Xunsigned long addr; Xint n; Xchar **pp; X{ X if (addr == (unsigned long)0) X *pp = (char *)0; X else X { X if (proc_mem_contiguous(addr, n, pp)) X return 0; X X if (bufset(n) == -1) X return -1; X X if (quiet_procmget(GLOBALdipc, addr, sys_call_buf, n) == -1) X return -1; X X *pp = sys_call_buf; X } X X return 0; X} X Xint Xmget(addr, p, n, pp) Xunsigned long addr; Xchar *p; Xint n; Xchar **pp; X{ X if (addr == (unsigned long)0) X *pp = (char *)0; X else X { X if (quiet_procmget(GLOBALdipc, addr, p, n) == -1) X return -1; X X *pp = p; X } X X return 0; X} X Xint Xdmput(addr, p, n, s) Xunsigned long addr; Xchar *p; Xint n; Xint s; X{ X if (s != -1 && addr != (unsigned long)0 && p != (char *)0) X { X if (proc_mem_contiguous(addr, n, (char **)0)) X return 0; X X if (quiet_procmput(GLOBALdipc, addr, p, n) == -1) X return -1; X } X X return 0; X} X Xint Xmput(addr, p, n, s) Xunsigned long addr; Xchar *p; Xint n; Xint s; X{ X if (s != -1 && addr != (unsigned long)0 && p != (char *)0) X { X if (quiet_procmput(GLOBALdipc, addr, p, n) == -1) X return -1; X } X X return 0; X} X Xstatic Xint Xget_syscall_arg(i, resultp) Xint i; Xunsigned long *resultp; X{ X unsigned long sp; X X switch (i) X { X case 0: X if (quiet_procsget(R_V0, resultp) == -1) X return -1; X break; X X case 1: X if (quiet_procsget(R_A0, resultp) == -1) X return -1; X break; X X case 2: X if (quiet_procsget(R_A1, resultp) == -1) X return -1; X break; X X case 3: X if (quiet_procsget(R_A2, resultp) == -1) X return -1; X break; X X case 4: X if (quiet_procsget(R_A3, resultp) == -1) X return -1; X break; X X default: X if (quiet_procsget(R_SP, &sp) == -1) X return -1; X X if (quiet_procmget(GLOBALdipc, sp + (i - 1) * sizeof(int), resultp, sizeof(*resultp)) == -1) X return -1; X break; X } X X return 0; X} X Xstatic Xvoid Xvis_char(outfp, c) XFILE *outfp; Xint c; X{ X if (c >= ' ' && c <= '~') X { X if (c == '\\' || c == '"') X fprintf(outfp, "\\"); X fprintf(outfp, "%c", c); X } X else X { X switch (c) X { X case '\b': X fprintf(outfp, "\\b"); X break; X X case '\f': X fprintf(outfp, "\\f"); X break; X X case '\n': X fprintf(outfp, "\\n"); X break; X X case '\r': X fprintf(outfp, "\\r"); X break; X X case '\t': X fprintf(outfp, "\\t"); X break; X X default: X fprintf(outfp, "\\%03o", c); X break; X } X } X} X Xstatic Xvoid Xvis_string_with_quotes(outfp, p) XFILE *outfp; Xchar *p; X{ X if (p == (char *)0) X fprintf(outfp, "(char *)0"); X else X { X fprintf(outfp, "\""); X while (*p != '\0') X vis_char(outfp, *p++); X fprintf(outfp, "\""); X } X} X Xvoid Xvis_quoted_truncated_buffer(outfp, truncated_length, buf, real_length) XFILE *outfp; Xint truncated_length; Xchar *buf; Xlong real_length; X{ X int i; X X if (buf == (char *)0) X fprintf(outfp, "(char *)0"); X else X { X fprintf(outfp, "\""); X for (i = 0; i < truncated_length; i++) X vis_char(outfp, buf[i]); X fprintf(outfp, "\"%s", (truncated_length < real_length) ? ".." : ""); X } X} X X/* X * See ~i/sys/signal.h X */ Xstatic char *signames[] = X{ X "NULLSIG", /* undefined */ X "SIGHUP", /* hangup */ X "SIGINT", /* interrupt (rubout) */ X "SIGQUIT", /* quit (ASCII FS) */ X "SIGILL", /* illegal instruction (not reset when caught)*/ X "SIGTRAP", /* trace trap (not reset when caught) */ X "SIGABRT/SIGIOT", /* IOT instruction used by abort */ X "SIGXCPU/SIGEMT", /* exceeded CPU time limit/EMT instruction */ X /* SIGEMT (not possible on RISC/os) */ X "SIGFPE", /* floating point exception */ X "SIGKILL", /* kill (cannot be caught or ignored) */ X "SIGBUS", /* bus error */ X "SIGSEGV", /* segmentation violation */ X "SIGSYS", /* bad argument to system call */ X "SIGPIPE", /* write on a pipe with no one to read it */ X "SIGALRM", /* alarm clock */ X "SIGTERM", /* software termination signal from kill */ X "SIGUSR1", /* user defined signal 1 */ X "SIGUSR2", /* user defined signal 2 */ X "SIGCLD/SIGCHLD", /* death of a child/4.3BSD's name */ X "SIGXFSZ/SIGPWR", /* exceeded file size limit/power-fail */ X /* SIGPWR not possible on RISC/os */ X "SIGSTOP", /* sendable stop signal not from tty */ X "SIGTSTP", /* stop signal from tty */ X "SIGPOLL", /* pollable event occured */ X "SIGIO", /* input/output possible signal */ X "SIGURG", /* urgent condition on IO channel */ X "SIGWINCH", /* window size changes */ X "SIGVTALRM", /* virtual time alarm */ X "SIGPROF", /* profiling alarm */ X "SIGCONT", /* continue a stopped process */ X "SIGTTIN", /* to readers pgrp upon background tty read */ X "SIGTTOU", /* like TTIN for output */ X /* -- if (tp->t_local<OSTOP) */ X "SIGLOST", /* resource lost (eg, record-lock) */ X}; X Xchar * Xsignal_name(s) Xunsigned long s; X{ X static char buf[128]; X int signo; X int bits; X X signo = s & SIGNO_MASK; X bits = s & ~SIGNO_MASK; X X if (signo >= 0 && signo < nels(signames)) X (void)strcpy(&buf[0], signames[signo]); X else X (void)sprintf(&buf[0], "%d", signo); X X if ((bits & SIGDEFER) == SIGDEFER) X { X bits &= ~SIGDEFER; X (void)strcat(&buf[0], "|SIGDEFER"); X } X X if ((bits & SIGHOLD) == SIGHOLD) X { X bits &= ~SIGHOLD; X (void)strcat(&buf[0], "|SIGHOLD"); X } X X if ((bits & SIGRELSE) == SIGRELSE) X { X bits &= ~SIGRELSE; X (void)strcat(&buf[0], "|SIGRELSE"); X } X X if ((bits & SIGIGNORE) == SIGIGNORE) X { X bits &= ~SIGIGNORE; X (void)strcat(&buf[0], "|SIGIGNORE"); X } X X if ((bits & SIGPAUSE) == SIGPAUSE) X { X bits &= ~SIGPAUSE; X (void)strcat(&buf[0], "|SIGPAUSE"); X } X X if (bits != 0x0) X (void)sprintf(&buf[0], "|0x%x", bits); X X return &buf[0]; X} X Xchar * Xsignal_set(mask) Xunsigned long mask; X{ X static char buf[1024]; X int s; X X buf[0] = '\0'; X X (void)strcat(&buf[0], "{"); X for (s = 1; s < NSIG; s++) X { X unsigned long m; X X m = sigmask(s); X if ((m & mask) == m) X { X (void)strcat(&buf[0], signames[s]); X (void)strcat(&buf[0], ","); X mask &= ~m; X } X } X (void)strcat(&buf[0], "}"); X X if (mask != 0x0) X (void)sprintf(&buf[strlen(&buf[0])], "0x%x", mask); X X return &buf[0]; X} X Xstatic char *family[] = X{ X "UNSPEC", X "UNIX", X "INET", X "IMPLINK", X "PUP", X "CHAOS", X "NS", X "NBS", X "ECMA", X "DATAKIT", X "CCITT", X "SNA", X "DECnet", X "DLI", X "LAT", X "HYLINK", X "APPLETALK", X}; X Xstatic Xchar * Xsay_family(f) Xint f; X{ X static char buf[16]; X X if (f < 0 || f >= nels(family)) X (void)sprintf(&buf[0], "%d", f); X else X { X (void)strcpy(&buf[0], "AF_"); X (void)strcat(&buf[0], family[f]); X } X X return &buf[0]; X} X Xstatic Xchar * Xsay_addr(a) Xunsigned long a; X{ X static char buf[32]; X int i; X X buf[0] = '\0'; X X for (i = 0; i < sizeof(a); i++) X { X if (i != 0) X buf[i * 4 - 1] = '.'; X X (void)sprintf(&buf[i * 4], "%03d", (a >> (24 - (i * 8))) & 0xFF); X } X X return &buf[0]; X} X Xstatic Xvoid Xvis_address(outfp, s) XFILE *outfp; Xstruct sockaddr *s; X{ X if (s->sa_family == AF_INET) X { X struct sockaddr_in is; X X *(struct sockaddr_in *)&is = *(struct sockaddr_in *)s; X fprintf(outfp, "{"); X fprintf(outfp, "port=%d,", is.sin_port); X fprintf(outfp, "addr=%s", say_addr(is.sin_addr.s_addr)); X fprintf(outfp, "}"); X } X else X vis_quoted_truncated_buffer(outfp, sizeof(s->sa_data), &s->sa_data[0], sizeof(s->sa_data)); X} X Xvoid Xsay_time(outfp, t) XFILE *outfp; Xunsigned long t; X{ X char *cp; X X cp = ctime(&t); X cp[24] = '\0'; /* overwrite the newline */ X fprintf(outfp, "%lu[%s]", t, cp); X} X Xint Xprintval(universe, arg, desc, args, return_value0, return_value1, direction) Xint universe; Xlong arg; Xint desc; Xlong *args; Xlong return_value0; Xlong return_value1; Xint direction; X{ X int length; X char **app; X char **cpp; X struct flock sheep; X X switch (desc) X { X case 'A': /* ioctl arg */ X switch (universe) X { X case U_SYSV: X return sysv_print_ioctl_arg(args); X X case U_BSD43: X return bsd43_print_ioctl_arg(args); X X case U_POSIX: X return posix_print_ioctl_arg(args); X X default: X vcouldnot("print ioctl arg from unknown universe %d", universe); X return -1; X } X break; X X case 'B': /* fcntl cmd */ X switch (arg) X { X case F_DUPFD: X fprintf(outfp, "F_DUPFD"); X break; X X case F_GETFD: X fprintf(outfp, "F_GETFD"); X break; X X case F_SETFD: X fprintf(outfp, "F_SETFD"); X break; X X case F_GETFL: X fprintf(outfp, "F_GETFL"); X break; X X case F_SETFL: X fprintf(outfp, "F_SETFL"); X break; X X case F_GETLK: X fprintf(outfp, "F_GETLK"); X break; X X case F_SETLK: X fprintf(outfp, "F_SETLK"); X break; X X case F_SETLKW: X fprintf(outfp, "F_SETLKW"); X break; X X case F_CHKFL: X fprintf(outfp, "F_CHKFL"); X break; X X case F_GETOWN: X fprintf(outfp, "F_GETOWN"); X break; X X case F_SETOWN: X fprintf(outfp, "F_SETOWN"); X break; X X case PFCSEXEC: X fprintf(outfp, "PFCSEXEC"); X break; X X case PFCREXEC: X fprintf(outfp, "PFCREXEC"); X break; X X case PFCRUN: X fprintf(outfp, "PFCRUN"); X break; X X case PFCSSTEP: X fprintf(outfp, "PFCSSTEP"); X break; X X case PFCCSIG: X fprintf(outfp, "PFCCSIG"); X break; X X case PFCWSTOP: X fprintf(outfp, "PFCWSTOP"); X break; X X case PFCGMASK: X fprintf(outfp, "PFCGMASK"); X break; X X case PFCSMASK: X fprintf(outfp, "PFCSMASK"); X break; X X case PFCSTOP: X fprintf(outfp, "PFCSTOP"); X break; X X case PFCGETPR: X fprintf(outfp, "PFCGETPR"); X break; X X case PFCGETUSEG: X fprintf(outfp, "PFCGETUSEG"); X break; X X case PFCGETREGS: X fprintf(outfp, "PFCGETREGS"); X break; X X default: X fprintf(outfp, "0x%x", arg); X break; X } X break; X X case 'C': /* ioctl cmd */ X switch (universe) X { X case U_SYSV: X return sysv_print_ioctl_cmd(arg); X X case U_BSD43: X return bsd43_print_ioctl_cmd(arg); X X case U_POSIX: X return posix_print_ioctl_cmd(arg); X X default: X vcouldnot("print ioctl cmd from unknown universe %d", universe); X return -1; X } X break; X X case 'D': /* select fd_set */ X switch (universe) X { X case U_SYSV: X return sysv_print_fdset(args[0], arg); X X case U_BSD43: X return bsd43_print_fdset(args[0], arg); X X case U_POSIX: X return posix_print_fdset(args[0], arg); X X default: X vcouldnot("print fdset from unknown universe %d", universe); X return -1; X } X break; X X case 'E': /* envp */ X fprintf(outfp, "{"); X if (Aflag) X { X if ((app = mgetvp(arg)) == (char **)0) X return -1; X X for (cpp = app; *cpp != (char *)0; cpp++) X { X vis_string_with_quotes(outfp, *cpp); X fprintf(outfp, ","); X } X X if (mfreevp(app) == -1) X return -1; X } X else X fprintf(outfp, ".."); X fprintf(outfp, "}"); X break; X X case 'F': /* filename */ X { X char *cp; X X if (mgets(arg, &cp) == -1) X return -1; X X vis_string_with_quotes(outfp, cp); X } X break; X X case 'G': /* getgroups() group set */ X fprintf(outfp, "{"); X if (direction == DIRN_EXIT) X { X length = return_value0; X X if (length < 0) X length = 0; X X if (bufset((unsigned int)length * sizeof(int)) == -1) X return -1; X X if (quiet_procmget(GLOBALdipc, (unsigned long)arg, sys_call_buf, length * sizeof(int)) == -1) X return -1; X X { X int i; X X for (i = 0; i < length; i++) X fprintf(outfp, "%d, ", ((int *)sys_call_buf)[i]); X } X } X fprintf(outfp, "}"); X break; X X case 'H': /* fcntl arg */ X switch (args[1]) X { X case F_DUPFD: X case F_GETFD: X case F_SETFD: X case F_GETFL: X case F_SETFL: X fprintf(outfp, "0x%x", arg); X break; X X case F_GETLK: X case F_SETLK: X case F_SETLKW: X if (quiet_procmget(GLOBALdipc, arg, (char *)&sheep, sizeof(sheep)) == -1) X return -1; X X fprintf(outfp, "{"); X fprintf(outfp, "type="); X switch (sheep.l_type) X { X case F_RDLCK: X fprintf(outfp, "F_RDLCK"); X break; X X case F_WRLCK: X fprintf(outfp, "F_WRLCK"); X break; X X case F_UNLCK: X fprintf(outfp, "F_UNLCK"); X break; X X default: X fprintf(outfp, "0x%x", sheep.l_type); X break; X } X fprintf(outfp, ","); X fprintf(outfp, "whence=%d,", sheep.l_whence); X fprintf(outfp, "start=%d,", sheep.l_start); X fprintf(outfp, "len=%d,", sheep.l_len); X fprintf(outfp, "sysid=%d,", sheep.l_sysid); X fprintf(outfp, "pid=%d,", sheep.l_pid); X fprintf(outfp, "}"); X break; X X default: X fprintf(outfp, "0x%x", arg); X break; X } X break; X X X case 'I': /* program address */ X fprintf(outfp, "%s", proc_text_address(arg)); X break; X X case 'J': /* signal action or program address */ X switch (arg) X { X case SIG_ERR: X fprintf(outfp, "SIG_ERR"); X break; X X case SIG_DFL: X fprintf(outfp, "SIG_DFL"); X break; X X case SIG_IGN: X fprintf(outfp, "SIG_IGN"); X break; X X case SIG_HOLD: X fprintf(outfp, "SIG_HOLD"); X break; X X default: X fprintf(outfp, "%s", proc_text_address(arg)); X break; X } X break; X X case 'K': /* signal name */ X fprintf(outfp, "%s", signal_name(arg)); X break; X X case 'L': /* struct sockaddr */ X if (arg == (unsigned long)0) X fprintf(outfp, "0x%x", arg); X else X { X struct sockaddr s; X X if (quiet_procmget(GLOBALdipc, arg, (char *)&s, sizeof(s)) == -1) X return -1; X X fprintf(outfp, "{"); X fprintf(outfp, "family=%s,", say_family(s.sa_family)); X fprintf(outfp, "sa_data="); X vis_address(outfp, &s); X fprintf(outfp, "}"); X } X break; X X case 'M': /* signal set mask */ X fprintf(outfp, "%s", signal_set(arg)); X break; X X case 'N': /* send()/recv() flags */ X if (arg == 0) X fprintf(outfp, "0x0"); X else X { X int need_bar; X X need_bar = 0; X if (arg & MSG_OOB) X { X fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_OOB"); X need_bar = 1; X arg &= ~MSG_OOB; X } X if (arg & MSG_PEEK) X { X fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_PEEK"); X need_bar = 1; X arg &= ~MSG_PEEK; X } X if (arg & MSG_DONTROUTE) X { X fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_DONTROUTE"); X need_bar = 1; X arg &= ~MSG_DONTROUTE; X } X if (arg) X fprintf(outfp, "%s0x%x", need_bar ? "|" : "", arg); X } X break; X X case 'O': /* open flags */ X switch (universe) X { X case U_SYSV: X return sysv_print_open_flags(arg); X X case U_BSD43: X return bsd43_print_open_flags(arg); X X case U_POSIX: X return posix_print_open_flags(arg); X X default: X vcouldnot("print open flags from unknown universe %d", universe); X return -1; X } X break; X X case 'P': /* access mode */ X if (arg == 0) X fprintf(outfp, "F_OK"); X else X { X int need_bar; X X need_bar = 0; X if (arg & R_OK) X { X fprintf(outfp, "%s%s", need_bar ? "|" : "", "R_OK"); X need_bar = 1; X arg &= ~R_OK; X } X if (arg & W_OK) X { X fprintf(outfp, "%s%s", need_bar ? "|" : "", "W_OK"); X need_bar = 1; X arg &= ~W_OK; X } X if (arg & X_OK) X { X fprintf(outfp, "%s%s", need_bar ? "|" : "", "X_OK"); X need_bar = 1; X arg &= ~X_OK; X } X if (arg) X fprintf(outfp, "%s0x%x", need_bar ? "|" : "", arg); X } X break; X X case 'Q': /* pair of int's (as in utime()) */ X if (arg == 0) X fprintf(outfp, "0x%x", arg); X else X { X int i[2]; X X if (quiet_procmget(GLOBALdipc, (unsigned long)arg, &i[0], sizeof(i)) == -1) X return -1; X X fprintf(outfp, "{"); X say_time(outfp, i[0]); X fprintf(outfp, ","); X say_time(outfp, i[1]); X fprintf(outfp, "}"); X } X break; X X case 'R': /* read() buffer */ X if (direction == DIRN_ENTRY || args[0] == 100) X fprintf(outfp, "\"\""); X else X { X char *cp; X X length = return_value0; X X if (length < 0) X length = 0; X else if (Aflag == 0 && length > TRUNCATED_READ_WRITE_LENGTH) X length = TRUNCATED_READ_WRITE_LENGTH; X X if (dmget((unsigned long)arg, length, &cp) == -1) X return -1; X X vis_quoted_truncated_buffer(outfp, length, cp, return_value0); X } X break; X X case 'S': /* struct stat */ X if (direction == DIRN_EXIT) X { X switch (universe) X { X case U_SYSV: X return sysv_print_stat(arg); X X case U_BSD43: X return bsd43_print_stat(arg); X X case U_POSIX: X return posix_print_stat(arg); X X default: X vcouldnot("print stat structure from unknown universe %d", universe); X return -1; X } X } X break; X X case 'T': /* struct timeval */ X if (arg == (unsigned long)0) X fprintf(outfp, "0x%x", arg); X else X { X struct timeval t; X X if (quiet_procmget(GLOBALdipc, arg, (char *)&t, sizeof(t)) == -1) X return -1; X X fprintf(outfp, "{"); X fprintf(outfp, "sec=%d,", t.tv_sec); X fprintf(outfp, "usec=%d", t.tv_usec); X fprintf(outfp, "}"); X } X break; X X case 'U': /* pointer to an int */ X if (arg == (unsigned long)0) X fprintf(outfp, "0x%x", arg); X else X { X int i; X X if (quiet_procmget(GLOBALdipc, arg, (char *)&i, sizeof(i)) == -1) X return -1; X X fprintf(outfp, "{%d}", i); X } X break; X X case 'V': /* pair of struct timeval's */ X if (arg == (unsigned long)0) X fprintf(outfp, "0x%x", arg); X else X { X struct timeval t[2]; X X if (quiet_procmget(GLOBALdipc, arg, &t[0], sizeof(t)) == -1) X return -1; X X fprintf(outfp, "{"); X fprintf(outfp, "{"); X fprintf(outfp, "sec=%d,", t[0].tv_sec); X fprintf(outfp, "usec=%d", t[0].tv_usec); X fprintf(outfp, "}"); X fprintf(outfp, "{"); X fprintf(outfp, "sec=%d,", t[1].tv_sec); X fprintf(outfp, "usec=%d", t[1].tv_usec); X fprintf(outfp, "}"); X fprintf(outfp, "}"); X } X break; X X case 'W': /* write() buffer */ X { X char *cp; X X length = args[2]; X X if (Aflag == 0 && length > TRUNCATED_READ_WRITE_LENGTH) X length = TRUNCATED_READ_WRITE_LENGTH; X X if (dmget((unsigned long)arg, length, &cp) == -1) X return -1; X X vis_quoted_truncated_buffer(outfp, length, cp, args[2]); X } X break; X X case 'X': /* struct statfs */ X switch (universe) X { X case U_SYSV: X return sysv_print_statfs(arg); X X case U_BSD43: X return bsd43_print_statfs(arg); X X case U_POSIX: X return posix_print_statfs(arg); X X default: X vcouldnot("print statfs structure from unknown universe %d", universe); X return -1; X } X break; X X case 'Y': /* result pair */ X fprintf(outfp, "{%d,%d}", return_value0, return_value1); X break; X X case 'Z': /* struct timezone */ X if (arg == (unsigned long)0) X fprintf(outfp, "0x%x", arg); X else X { X struct timezone t; X X if (quiet_procmget(GLOBALdipc, arg, (char *)&t, sizeof(t)) == -1) X return -1; X X fprintf(outfp, "{"); X fprintf(outfp, "minuteswest=%d,", t.tz_minuteswest); X fprintf(outfp, "dsttime=%d", t.tz_dsttime); X fprintf(outfp, "}"); X } X break; X X case 'a': /* socket domain */ X switch (arg) X { X case PF_UNIX: X fprintf(outfp, "PF_UNIX"); X break; X X case PF_INET: X fprintf(outfp, "PF_INET"); X break; X X case PF_NS: X fprintf(outfp, "PF_NS"); X break; X X case PF_IMPLINK: X fprintf(outfp, "PF_IMPLINK"); X break; X X default: X fprintf(outfp, "%d", arg); X break; X } X break; X X case 'b': /* socket type */ X switch (arg) X { X case SOCK_STREAM: X fprintf(outfp, "SOCK_STREAM"); X break; X X case SOCK_DGRAM: X fprintf(outfp, "SOCK_DGRAM"); X break; X X case SOCK_RAW: X fprintf(outfp, "SOCK_RAW"); X break; X X case SOCK_SEQPACKET: X fprintf(outfp, "SOCK_SEQPACKET"); X break; X X case SOCK_RDM: X fprintf(outfp, "SOCK_RDM"); X break; X X default: X fprintf(outfp, "%d", arg); X break; X } X break; X X case 'c': /* socket protocol */ X { X struct protoent *p; X X if X ( X args[0] == PF_INET X && X (p = getprotobynumber(arg)) != (struct protoent *)0 X ) X fprintf(outfp, "%s", p->p_name); X else X fprintf(outfp, "%d", arg); X } X break; X X case 'd': /* int */ X fprintf(outfp, "%d", arg); X break; X X case 'e': /* int -- result from execve()/exit() see i_syscall() */ X fprintf(outfp, "%d", arg); X break; X X case 'f': /* pointer to a struct sigvec */ X if (bsd43_print_sigvec(arg) == -1) X return -1; X break; X X case 'g': /* setgroups() group set */ X fprintf(outfp, "{"); X { X length = args[0]; X X if (length < 0) X length = 0; X X if (bufset((unsigned int)length * sizeof(int)) == -1) X return -1; X X if (quiet_procmget(GLOBALdipc, (unsigned long)arg, sys_call_buf, length * sizeof(int)) == -1) X return -1; X X { X int i; X X for (i = 0; i < length; i++) X fprintf(outfp, "%d, ", ((int *)sys_call_buf)[i]); X } X } X fprintf(outfp, "}"); X break; X X case 'h': /* wait3 union wait */ X if (sysv_print_wait3_union_wait(arg) == -1) X return -1; X break; X X case 'i': /* wait3 options */ X if (sysv_print_wait3_options(arg) == -1) X return -1; X break; X X case 'j': /* wait3 rusage */ X if (sysv_print_wait3_rusage(arg) == -1) X return -1; X break; X X case 'k': /* times tms */ X { X struct tms t; X struct tms *tp; X X if (mget(arg, &t, sizeof(t), &tp) == -1) X return -1; X X if (tp == (struct tms *)0) X fprintf(outfp, "0x%x", arg); X else X { X fprintf(outfp, "{" /* } */); X X fprintf(outfp, "utime=%d,", t.tms_utime); X fprintf(outfp, "stime=%d,", t.tms_stime); X fprintf(outfp, "cutime=%d,", t.tms_cutime); X fprintf(outfp, "cstime=%d,", t.tms_cstime); X X fprintf(outfp, /* { */ "}"); X } X X return 0; X } X break; X X case 'l': /* argp */ X fprintf(outfp, "{"); X if (Aflag) X { X if ((app = mgetvp(arg)) == (char **)0) X return -1; X X for (cpp = app; *cpp != (char *)0; cpp++) X { X vis_string_with_quotes(outfp, *cpp); X fprintf(outfp, ","); X } X X if (mfreevp(app) == -1) X return -1; X } X else X fprintf(outfp, ".."); X fprintf(outfp, "}"); X break; X X case 'm': /* file creation mode */ X fprintf(outfp, "%s%o", (arg == 0) ? "" : "0", arg); X break; X X case 'o': /* octal int */ X fprintf(outfp, "%s%o", (arg == 0) ? "" : "0", arg); X break; X X case 'p': /* pointer */ X case 'x': /* " */ X fprintf(outfp, "0x%x", arg); X break; X X case 's': /* outgoing string */ X if (direction == DIRN_EXIT) X { X char *cp; X X if (mgets(arg, &cp) == -1) X return -1; X X vis_string_with_quotes(outfp, cp); X } X break; X X case 't': /* time_t */ X say_time(outfp, arg); X break; X X case 'u': /* unsigned long */ X fprintf(outfp, "%lu", arg); X break; X X case 'v': /* pointer to a time_t */ X if (arg == (unsigned long)0) X fprintf(outfp, "0x%x", arg); X else X { X long i; X X if (quiet_procmget(GLOBALdipc, arg, (char *)&i, sizeof(i)) == -1) X return -1; X X fprintf(outfp, "{"); X say_time(outfp, i); X fprintf(outfp, "}"); X } X break; X X case 'w': /* lseek() whence */ X switch (universe) X { X case U_SYSV: X return sysv_print_whence(arg); X X case U_BSD43: X return bsd43_print_whence(arg); X X case U_POSIX: X return posix_print_whence(arg); X X default: X vcouldnot("print whence from unknown universe %d", universe); X return -1; X } X break; X X case 'y': /* sigcontext */ X switch (universe) X { X case U_SYSV: X return sysv_print_sigcontext(outfp, arg); X X case U_BSD43: X return bsd43_print_sigcontext(outfp, arg); X X case U_POSIX: X return posix_print_sigcontext(outfp, arg); X X default: X vcouldnot("print sigcontext from unknown universe %d", universe); X return -1; X } X break; X X case '\0': /* unknown */ X default: /* " */ X fprintf(outfp, "0x%x", arg); X break; X } X X return 0; X} X Xstatic Xchar * Xsay_errno(e) Xint e; X{ X if (e < 0 || e >= sys_nerrno) X e = 0; X X return sys_errnolist[e]; X} X Xstatic Xint Xshow_syscall(universe, universe_name, current_sysentp, argp, return_value0, return_value1, return_errno, direction) Xint universe; Xchar *universe_name; Xsysentry *current_sysentp; Xunsigned long *argp; Xlong return_value0; Xlong return_value1; Xint return_errno; Xint direction; X{ X int i; X X fprintf(outfp, "%6d:", P.p_pid); X X fprintf(outfp, "%s_", universe_name); X X fprintf(outfp, "%s(", (current_sysentp->sy_name == (char *)0) ? "" : current_sysentp->sy_name); X X for (i = 0; i < current_sysentp->sy_narg; i++) X { X if (i != 0) X fprintf(outfp, ", "); X if (printval(universe, argp[i], (int)current_sysentp->sy_desc[i], argp, return_value0, return_value1, direction) == -1) X return -1; X } X X fprintf(outfp, ")"); X X if (direction == DIRN_EXIT) X { X fprintf(outfp, " = "); X X if (printval(universe, return_value0, (int)current_sysentp->sy_rdesc, argp, return_value0, return_value1, direction) == -1) X return -1; X X if (return_errno != 0) X { X int saved_errno; X X saved_errno = errno; X errno = return_errno; X fprintf(outfp, " %s (%s)", say_errno(return_errno), sysmess()); X errno = saved_errno; X } X } X X if (Nflag) X { X fprintf(outfp, " [%d,%d]", instruction_count_since_last_syscall, instruction_count); X instruction_count_since_last_syscall = 0; X } X X if (Tflag) X res_print(); X X fprintf(outfp, "\n"); X X return 0; X} X Xdinstrn * Xi_syscall(dipc, rs, rt, rd, shamt, funct) Xdinstrn *dipc; Xint rs; Xint rt; Xint rd; Xint shamt; Xint funct; X{ X int stacki; X unsigned long real_syscall_number; X int syscall_number; X int universe; X char *universe_name; X int argi; X int r; X int (*fp)(); X X errno = 0; X X stacki = 0; X X current_sysentp = (sysentry *)0; X universe_name = ""; X X GLOBALdipc = dipc; X X /* X * Determine the system call number, X * doing any indirection as required. X */ X for (;;) X { X if (get_syscall_arg(stacki++, &real_syscall_number) == -1) X return dipc; X X syscall_number = real_syscall_number % 1000; X X /* X * This next test should really refer to X * SYS_syscall X * BSD43_SYS_syscall X * POSIX_SYS_syscall X * but the latter exists instead as X * SYS_syscall X * which would cause an embarrassing X * name clash. X * They all expand to 0 anyway, X * so that's what we use. X */ X if (syscall_number == 0) X continue; X X switch (universe = real_syscall_number / 1000) X { X case U_SYSV: X universe_name = "sysv"; X current_sysentp = sysv_systab_entry(syscall_number); X break; X X case U_BSD43: X universe_name = "bsd43"; X current_sysentp = bsd43_systab_entry(syscall_number); X break; X X case U_POSIX: X universe_name = "posix"; X current_sysentp = posix_systab_entry(syscall_number); X break; X X case 0: X default: X break; X } X X break; X } X X if (current_sysentp == (sysentry *)0) X { X vcouldnot("execute unimplemented %s system call #%d", universe_name, real_syscall_number); X return dipc; X } X X if ((fp = current_sysentp->sy_call) == (int (*)())0) X { X vcouldnot("execute unimplemented %s system call \"%s\" [#%d]", universe_name, (current_sysentp->sy_name == (char *)0) ? "" : current_sysentp->sy_name, real_syscall_number); X return dipc; X } X X /* X * Get the system call's arguments. X */ X for (argi = 0; argi < current_sysentp->sy_narg; argi++) X { X if (get_syscall_arg(stacki++, &arg[argi]) == -1) X return dipc; X } X X /* X * Print system call arguments before execution if desired. X * (The 'e' kludge is for execve() and exit()...) X */ X if (Pflag || (Sflag && current_sysentp->sy_rdesc == 'e')) X { X if (show_syscall(universe, universe_name, current_sysentp, &arg[0], (long)0, (long)0, 0, DIRN_ENTRY) == -1) X return dipc; X } X X /* X * Run the system call. X */ X switch (r = (*fp)(real_syscall_number)) X { X case 0: /* OK */ X dipc = GLOBALdipc; X break; X X case -1: /* Some internal error. */ X dipc = GLOBALdipc; X return dipc; X X case -2: /* Unimpl. feature. */ X dipc = GLOBALdipc; X if (!Pflag && !(Sflag && current_sysentp->sy_rdesc == 'e')) X { X if (show_syscall(universe, universe_name, current_sysentp, &arg[0], (long)0, (long)0, 0, DIRN_ENTRY) == -1) X return dipc; X } X X vcouldnot("execute unimplemented feature of %s system call \"%s\" [#%d]", universe_name, (current_sysentp->sy_name == (char *)0) ? "" : current_sysentp->sy_name, real_syscall_number); X return dipc; X X case -3: /* OK, but don't copy errno/values to registers. */ X dipc = GLOBALdipc; X break; X X default: /* Somebody stuffed up ... */ X dipc = GLOBALdipc; X vcouldnot("execute %s system call \"%s\" [#%d]: unrecognised return value: %d", universe_name, (current_sysentp->sy_name == (char *)0) ? "" : current_sysentp->sy_name, real_syscall_number, r); X return dipc; X } X X if (r != -3) X { X /* X * Pass back errno and return values. X */ X if (return_errno == 0) X { X if (quiet_procsput(R_V0, (unsigned long)return_value0) == -1) X return dipc; X X if (quiet_procsput(R_V1, (unsigned long)return_value1) == -1) X return dipc; X X if (quiet_procsput(R_A3, 0) == -1) X return dipc; X } X else X { X if (quiet_procsput(R_V0, (unsigned long)return_errno) == -1) X return dipc; X X if (quiet_procsput(R_A3, 1) == -1) X return dipc; X } X } X X /* X * Print system call arguments and results X * after execution if desired. X */ X if (Sflag) X { X if (show_syscall(universe, universe_name, current_sysentp, &arg[0], return_value0, return_value1, return_errno, DIRN_EXIT) == -1) X return dipc; X } X X return dipc; X} END_OF_FILE if test 33351 -ne `wc -c <'i_syscall.c'`; then echo shar: \"'i_syscall.c'\" unpacked with wrong size! fi # end of 'i_syscall.c' fi echo shar: End of archive 6 \(of 8\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0