home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / trash / part06 / i_syscall.c
Encoding:
C/C++ Source or Header  |  1992-03-22  |  32.6 KB  |  1,839 lines

  1. #include    <sys/types.h>
  2. #include    <sys/times.h>
  3. #include    <sys/fs/prfcntl.h>
  4. #include    <bsd/sys/types.h>
  5. #include    <bsd/sys/socket.h>
  6. #include    <bsd/sys/time.h>
  7. #include    <bsd/netinet/in.h>
  8. #include    <bsd/netdb.h>
  9. #define    INKERNEL    1
  10. #include    <signal.h>
  11. #undef    INKERNEL
  12. #include    <fcntl.h>
  13. #include    <errno.h>
  14. #include    <stdio.h>
  15. #include    <unistd.h>
  16. #include    "register.h"
  17. #include    "symtab.h"
  18. #include    "diblock.h"
  19. #include    "instrn.h"
  20. #include    "process.h"
  21. #include    "sysentry.h"
  22. #include    "res.h"
  23. #include    "nels.h"
  24.  
  25. #define            TRUNCATED_READ_WRITE_LENGTH    32
  26.  
  27. extern char        *malloc();
  28. extern char        *realloc();
  29. extern char        *ctime();
  30. extern char        *sysmess();
  31. extern sysentry        *sysv_systab_entry();
  32. extern sysentry        *bsd43_systab_entry();
  33. extern sysentry        *posix_systab_entry();
  34.  
  35. extern int        sysv_print_open_flags();
  36. extern int        bsd43_print_open_flags();
  37. extern int        posix_print_open_flags();
  38.  
  39. extern int        sysv_print_open_mode();
  40. extern int        bsd43_print_open_mode();
  41. extern int        posix_print_open_mode();
  42.  
  43. extern int        sysv_print_stat();
  44. extern int        bsd43_print_stat();
  45. extern int        posix_print_stat();
  46.  
  47. extern int        sysv_print_ioctl_cmd();
  48. extern int        bsd43_print_ioctl_cmd();
  49. extern int        posix_print_ioctl_cmd();
  50.  
  51. extern int        sysv_print_ioctl_arg();
  52. extern int        bsd43_print_ioctl_arg();
  53. extern int        posix_print_ioctl_arg();
  54.  
  55. extern int        sysv_print_fdset();
  56. extern int        bsd43_print_fdset();
  57. extern int        posix_print_fdset();
  58.  
  59. extern int        sysv_print_whence(); 
  60. extern int        bsd43_print_whence(); 
  61. extern int        posix_print_whence(); 
  62.  
  63. extern int        sysv_print_statfs(); 
  64. extern int        bsd43_print_statfs(); 
  65. extern int        posix_print_statfs(); 
  66.  
  67. extern int        sysv_print_sigcontext(); 
  68. extern int        bsd43_print_sigcontext(); 
  69. extern int        posix_print_sigcontext(); 
  70.  
  71. extern int        bsd43_print_sigvec(); 
  72. extern int        sysv_print_wait3_union_wait(); 
  73. extern int        sysv_print_wait3_options(); 
  74. extern int        sysv_print_wait3_rusage(); 
  75.  
  76. extern int        Aflag;
  77. extern int        Iflag;
  78. extern int        Nflag;
  79. extern int        Pflag;
  80. extern int        Sflag;
  81. extern int        Tflag;
  82.  
  83. extern char        *sys_errnolist[];
  84. extern int        sys_nerrno;
  85. extern FILE        *outfp;
  86. extern int        errno;
  87. extern unsigned long    instruction_count;
  88. extern unsigned long    instruction_count_since_last_syscall;
  89.  
  90. unsigned long        arg[NSYSARGS];    /* Arguments */
  91.  
  92. dinstrn            *GLOBALdipc;
  93. int            return_errno;    /* errno goes here. */
  94. long            return_value0;    /* Result 1 value goes here. */
  95. long            return_value1;    /* Result 2 value goes here. */
  96.  
  97. sysentry        *current_sysentp;
  98. char            *sys_call_buf;    /* Scratch buf. */
  99. unsigned int        sys_call_bufz;    /* Current size of above. */
  100.  
  101. int            need_leading_pipe;
  102.  
  103. /*
  104.  * Ensure that the scratch buffer (pointed to by 'sys_call_buf')
  105.  * is at least 'n' bytes long.
  106.  * Return -1 on error.
  107.  */
  108. int
  109. bufset(n)
  110. unsigned int    n;
  111. {
  112.     if (sys_call_bufz >= n)
  113.         return 0;
  114.  
  115.     if (sys_call_bufz == 0)
  116.         sys_call_buf = malloc(n);
  117.     else
  118.         sys_call_buf = realloc(sys_call_buf, n);
  119.  
  120.     if (sys_call_buf == (char *)0)
  121.     {
  122.         vcouldnot("expand syscall buffer to %d bytes", n);
  123.         return -1;
  124.     }
  125.  
  126.     sys_call_bufz = n;
  127.  
  128.     return 0;
  129. }
  130.  
  131. /*
  132.  * Return the length of the string that starts
  133.  * at address 'addr' in user memory (like strlen()).
  134.  * Return -1 on error.
  135.  */
  136. int
  137. mstrlen(addr)
  138. unsigned long    addr;
  139. {
  140.     int    length;
  141.     char    c;
  142.  
  143.     length = 0;
  144.  
  145.     for (;;)
  146.     {
  147.         if (quiet_procmget(GLOBALdipc, addr, &c, sizeof(c)) == -1)
  148.             return -1;
  149.  
  150.         if (c == '\0')
  151.             break;
  152.  
  153.         length++;
  154.         addr++;
  155.     }
  156.  
  157.     return length;
  158. }
  159.  
  160. int
  161. mgetstring(p)
  162. long    p;
  163. {
  164.     int    length;
  165.  
  166.     if ((length = mstrlen(p)) == -1)
  167.         return -1;
  168.  
  169.     length++;
  170.  
  171.     if (bufset((unsigned int)length) == -1)
  172.         return -1;
  173.  
  174.     if (quiet_procmget(GLOBALdipc, (unsigned long)p, sys_call_buf, length) == -1)
  175.         return -1;
  176.  
  177.     return length;
  178. }
  179.  
  180. int
  181. mgets(addr, pp)
  182. unsigned long    addr;
  183. char        **pp;
  184. {
  185.     int    length;
  186.  
  187.     if (addr == (unsigned long)0)
  188.     {
  189.         *pp = (char *)0;
  190.         return 0;
  191.     }
  192.  
  193.     if ((length = mstrlen(addr)) == -1)
  194.         return -1;
  195.  
  196.     length++;
  197.  
  198.     if (bufset((unsigned int)length) == -1)
  199.         return -1;
  200.  
  201.     if (quiet_procmget(GLOBALdipc, addr, sys_call_buf, length) == -1)
  202.         return -1;
  203.  
  204.     *pp = sys_call_buf;
  205.  
  206.     return length;
  207. }
  208.  
  209. int
  210. mputstring(p)
  211. long    p;
  212. {
  213.     int    length;
  214.  
  215.     length = strlen(sys_call_buf);
  216.  
  217.     length++;
  218.  
  219.     if (quiet_procmput(GLOBALdipc, (unsigned long)p, sys_call_buf, length) == -1)
  220.         return -1;
  221.  
  222.     return length;
  223. }
  224.  
  225. char    **
  226. mgetvp(addr)
  227. unsigned long    addr;
  228. {
  229.     int        nargs;
  230.     int        nchars;
  231.     char        **result;
  232.     unsigned long    saved_addr;
  233.     char        **pp;
  234.     char        *stringp;
  235.  
  236.     saved_addr = addr;
  237.     nargs = 0;
  238.     nchars = 0;
  239.  
  240.     for (;;)
  241.     {
  242.         char    *p;
  243.         int    length;
  244.  
  245.         if (quiet_procmget(GLOBALdipc, addr, &p, sizeof(p)) == -1)
  246.             return (char **)0;
  247.  
  248.         if (p == (char *)0)
  249.             break;
  250.  
  251.         if ((length = mstrlen(p)) == -1)
  252.             return (char **)0;
  253.  
  254.         nargs++;
  255.         nchars += (length + 1);
  256.         addr += sizeof(p);
  257.     }
  258.  
  259.     nargs++;
  260.  
  261.     addr = saved_addr;
  262.  
  263.     if ((result = (char **)malloc(sizeof(char *) * nargs + nchars)) == (char **)0)
  264.     {
  265.         vcouldnot("allocate %d bytes during execve arg processing", sizeof(char *) * nargs + nchars);
  266.         return (char **)0;
  267.     }
  268.  
  269.     pp = result;
  270.     stringp = (char *)(result + nargs);
  271.  
  272.     for (;;)
  273.     {
  274.         char    *p;
  275.         int    length;
  276.  
  277.         if (quiet_procmget(GLOBALdipc, addr, &p, sizeof(p)) == -1)
  278.             return (char **)0;
  279.  
  280.         if (p == (char *)0)
  281.             break;
  282.  
  283.         if (mgetstring(p) == -1)
  284.             return (char **)0;
  285.  
  286.         *pp++ = stringp;
  287.  
  288.         (void)strcpy(stringp, sys_call_buf);
  289.         stringp += (strlen(sys_call_buf) + 1);
  290.  
  291.         addr += sizeof(p);
  292.     }
  293.  
  294.     *pp = (char *)0;
  295.  
  296.     return result;
  297. }
  298.  
  299. int
  300. mfreevp(p)
  301. char    **p;
  302. {
  303.     char    **cpp;
  304.  
  305.     for (cpp = p; *cpp != (char *)0; cpp++)
  306.         (void)free(*cpp);
  307.  
  308.     (void)free((char *)cpp);
  309.  
  310.     return 0;
  311. }
  312.  
  313. int
  314. dmget(addr, n, pp)
  315. unsigned long    addr;
  316. int        n;
  317. char        **pp;
  318. {
  319.     if (addr == (unsigned long)0)
  320.         *pp = (char *)0;
  321.     else
  322.     {
  323.         if (proc_mem_contiguous(addr, n, pp))
  324.             return 0;
  325.  
  326.         if (bufset(n) == -1)
  327.             return -1;
  328.  
  329.         if (quiet_procmget(GLOBALdipc, addr, sys_call_buf, n) == -1)
  330.             return -1;
  331.  
  332.         *pp = sys_call_buf;
  333.     }
  334.  
  335.     return 0;
  336. }
  337.  
  338. int
  339. mget(addr, p, n, pp)
  340. unsigned long    addr;
  341. char        *p;
  342. int        n;
  343. char        **pp;
  344. {
  345.     if (addr == (unsigned long)0)
  346.         *pp = (char *)0;
  347.     else
  348.     {
  349.         if (quiet_procmget(GLOBALdipc, addr, p, n) == -1)
  350.             return -1;
  351.  
  352.         *pp = p;
  353.     }
  354.  
  355.     return 0;
  356. }
  357.  
  358. int
  359. dmput(addr, p, n, s)
  360. unsigned long    addr;
  361. char        *p;
  362. int        n;
  363. int        s;
  364. {
  365.     if (s != -1 && addr != (unsigned long)0 && p != (char *)0)
  366.     {
  367.         if (proc_mem_contiguous(addr, n, (char **)0))
  368.             return 0;
  369.  
  370.         if (quiet_procmput(GLOBALdipc, addr, p, n) == -1)
  371.             return -1;
  372.     }
  373.  
  374.     return 0;
  375. }
  376.  
  377. int
  378. mput(addr, p, n, s)
  379. unsigned long    addr;
  380. char        *p;
  381. int        n;
  382. int        s;
  383. {
  384.     if (s != -1 && addr != (unsigned long)0 && p != (char *)0)
  385.     {
  386.         if (quiet_procmput(GLOBALdipc, addr, p, n) == -1)
  387.             return -1;
  388.     }
  389.  
  390.     return 0;
  391. }
  392.  
  393. static
  394. int
  395. get_syscall_arg(i, resultp)
  396. int        i;
  397. unsigned long    *resultp;
  398. {
  399.     unsigned long    sp;
  400.  
  401.     switch (i)
  402.     {
  403.     case 0:
  404.         if (quiet_procsget(R_V0, resultp) == -1)
  405.             return -1;
  406.         break;
  407.  
  408.     case 1:
  409.         if (quiet_procsget(R_A0, resultp) == -1)
  410.             return -1;
  411.         break;
  412.  
  413.     case 2:
  414.         if (quiet_procsget(R_A1, resultp) == -1)
  415.             return -1;
  416.         break;
  417.  
  418.     case 3:
  419.         if (quiet_procsget(R_A2, resultp) == -1)
  420.             return -1;
  421.         break;
  422.  
  423.     case 4:
  424.         if (quiet_procsget(R_A3, resultp) == -1)
  425.             return -1;
  426.         break;
  427.  
  428.     default:
  429.         if (quiet_procsget(R_SP, &sp) == -1)
  430.             return -1;
  431.  
  432.         if (quiet_procmget(GLOBALdipc, sp + (i - 1) * sizeof(int), resultp, sizeof(*resultp)) == -1)
  433.             return -1;
  434.         break;
  435.     }
  436.  
  437.     return 0;
  438. }
  439.  
  440. static
  441. void
  442. vis_char(outfp, c)
  443. FILE    *outfp;
  444. int    c;
  445. {
  446.     if (c >= ' ' && c <= '~') 
  447.     {
  448.         if (c == '\\' || c == '"')
  449.             fprintf(outfp, "\\");
  450.         fprintf(outfp, "%c", c);
  451.     }
  452.     else
  453.     {
  454.         switch (c)
  455.         {
  456.         case '\b':
  457.             fprintf(outfp, "\\b");
  458.             break;
  459.  
  460.         case '\f':
  461.             fprintf(outfp, "\\f");
  462.             break;
  463.  
  464.         case '\n':
  465.             fprintf(outfp, "\\n");
  466.             break;
  467.  
  468.         case '\r':
  469.             fprintf(outfp, "\\r");
  470.             break;
  471.  
  472.         case '\t':
  473.             fprintf(outfp, "\\t");
  474.             break;
  475.  
  476.         default:
  477.             fprintf(outfp, "\\%03o", c);
  478.             break;
  479.         }
  480.     }
  481. }
  482.  
  483. static
  484. void
  485. vis_string_with_quotes(outfp, p)
  486. FILE    *outfp;
  487. char    *p;
  488. {
  489.     if (p == (char *)0)
  490.         fprintf(outfp, "(char *)0");
  491.     else
  492.     {
  493.         fprintf(outfp, "\"");
  494.         while (*p != '\0')
  495.             vis_char(outfp, *p++);
  496.         fprintf(outfp, "\"");
  497.     }
  498. }
  499.  
  500. void
  501. vis_quoted_truncated_buffer(outfp, truncated_length, buf, real_length)
  502. FILE    *outfp;
  503. int    truncated_length;
  504. char    *buf;
  505. long    real_length;
  506. {
  507.     int    i;
  508.  
  509.     if (buf == (char *)0)
  510.         fprintf(outfp, "(char *)0");
  511.     else
  512.     {
  513.         fprintf(outfp, "\"");
  514.         for (i = 0; i < truncated_length; i++)
  515.             vis_char(outfp, buf[i]);
  516.         fprintf(outfp, "\"%s", (truncated_length < real_length) ? ".." : "");
  517.     }
  518. }
  519.  
  520. /*
  521.  * See ~i/sys/signal.h
  522.  */
  523. static char    *signames[]    =
  524. {
  525.     "NULLSIG",        /* undefined */
  526.     "SIGHUP",        /* hangup */
  527.     "SIGINT",        /* interrupt (rubout) */
  528.     "SIGQUIT",        /* quit (ASCII FS) */
  529.     "SIGILL",        /* illegal instruction (not reset when caught)*/
  530.     "SIGTRAP",        /* trace trap (not reset when caught) */
  531.     "SIGABRT/SIGIOT",    /* IOT instruction used by abort */
  532.     "SIGXCPU/SIGEMT",    /* exceeded CPU time limit/EMT instruction */
  533.                 /* SIGEMT (not possible on RISC/os) */
  534.     "SIGFPE",        /* floating point exception */
  535.     "SIGKILL",        /* kill (cannot be caught or ignored) */
  536.     "SIGBUS",        /* bus error */
  537.     "SIGSEGV",        /* segmentation violation */
  538.     "SIGSYS",        /* bad argument to system call */
  539.     "SIGPIPE",        /* write on a pipe with no one to read it */
  540.     "SIGALRM",        /* alarm clock */
  541.     "SIGTERM",        /* software termination signal from kill */
  542.     "SIGUSR1",        /* user defined signal 1 */
  543.     "SIGUSR2",        /* user defined signal 2 */
  544.     "SIGCLD/SIGCHLD",    /* death of a child/4.3BSD's name */
  545.     "SIGXFSZ/SIGPWR",    /* exceeded file size limit/power-fail */
  546.                 /* SIGPWR not possible on RISC/os */
  547.     "SIGSTOP",        /* sendable stop signal not from tty */
  548.     "SIGTSTP",        /* stop signal from tty */
  549.     "SIGPOLL",        /* pollable event occured */
  550.     "SIGIO",        /* input/output possible signal */
  551.     "SIGURG",        /* urgent condition on IO channel */
  552.     "SIGWINCH",        /* window size changes */
  553.     "SIGVTALRM",        /* virtual time alarm */
  554.     "SIGPROF",        /* profiling alarm */
  555.     "SIGCONT",        /* continue a stopped process */
  556.     "SIGTTIN",        /* to readers pgrp upon background tty read */
  557.     "SIGTTOU",        /* like TTIN for output */
  558.                 /* -- if (tp->t_local<OSTOP) */
  559.     "SIGLOST",        /* resource lost (eg, record-lock) */
  560. };
  561.  
  562. char    *
  563. signal_name(s)
  564. unsigned long    s;
  565. {
  566.     static char    buf[128];
  567.     int        signo;
  568.     int        bits;
  569.  
  570.     signo = s & SIGNO_MASK;
  571.     bits = s & ~SIGNO_MASK;
  572.  
  573.     if (signo >= 0 && signo < nels(signames))
  574.         (void)strcpy(&buf[0], signames[signo]);
  575.     else
  576.         (void)sprintf(&buf[0], "%d", signo);
  577.  
  578.     if ((bits & SIGDEFER) == SIGDEFER)
  579.     {
  580.         bits &= ~SIGDEFER;
  581.         (void)strcat(&buf[0], "|SIGDEFER");
  582.     }
  583.  
  584.     if ((bits & SIGHOLD) == SIGHOLD)
  585.     {
  586.         bits &= ~SIGHOLD;
  587.         (void)strcat(&buf[0], "|SIGHOLD");
  588.     }
  589.  
  590.     if ((bits & SIGRELSE) == SIGRELSE)
  591.     {
  592.         bits &= ~SIGRELSE;
  593.         (void)strcat(&buf[0], "|SIGRELSE");
  594.     }
  595.  
  596.     if ((bits & SIGIGNORE) == SIGIGNORE)
  597.     {
  598.         bits &= ~SIGIGNORE;
  599.         (void)strcat(&buf[0], "|SIGIGNORE");
  600.     }
  601.  
  602.     if ((bits & SIGPAUSE) == SIGPAUSE)
  603.     {
  604.         bits &= ~SIGPAUSE;
  605.         (void)strcat(&buf[0], "|SIGPAUSE");
  606.     }
  607.  
  608.     if (bits != 0x0)
  609.         (void)sprintf(&buf[0], "|0x%x", bits);
  610.  
  611.     return &buf[0];
  612. }
  613.  
  614. char    *
  615. signal_set(mask)
  616. unsigned long    mask;
  617. {
  618.     static char    buf[1024];
  619.     int        s;
  620.  
  621.     buf[0] = '\0';
  622.  
  623.     (void)strcat(&buf[0], "{");
  624.     for (s = 1; s < NSIG; s++)
  625.     {
  626.         unsigned long    m;
  627.  
  628.         m = sigmask(s);
  629.         if ((m & mask) == m)
  630.         {
  631.             (void)strcat(&buf[0], signames[s]);
  632.             (void)strcat(&buf[0], ",");
  633.             mask &= ~m;
  634.         }
  635.     }
  636.     (void)strcat(&buf[0], "}");
  637.  
  638.     if (mask != 0x0)
  639.         (void)sprintf(&buf[strlen(&buf[0])], "0x%x", mask);
  640.  
  641.     return &buf[0];
  642. }
  643.  
  644. static char    *family[]    =
  645. {
  646.     "UNSPEC",
  647.     "UNIX",
  648.     "INET",
  649.     "IMPLINK",
  650.     "PUP",
  651.     "CHAOS",
  652.     "NS",
  653.     "NBS",
  654.     "ECMA",
  655.     "DATAKIT",
  656.     "CCITT",
  657.     "SNA",
  658.     "DECnet",
  659.     "DLI",
  660.     "LAT",
  661.     "HYLINK",
  662.     "APPLETALK",
  663. };
  664.  
  665. static
  666. char    *
  667. say_family(f)
  668. int    f;
  669. {
  670.     static char    buf[16];
  671.  
  672.     if (f < 0 || f >= nels(family))
  673.         (void)sprintf(&buf[0], "%d", f);
  674.     else
  675.     {
  676.         (void)strcpy(&buf[0], "AF_");
  677.         (void)strcat(&buf[0], family[f]);
  678.     }
  679.  
  680.     return &buf[0];
  681. }
  682.  
  683. static
  684. char    *
  685. say_addr(a)
  686. unsigned long    a;
  687. {
  688.     static char    buf[32];
  689.     int        i;
  690.  
  691.     buf[0] = '\0';
  692.  
  693.     for (i = 0; i < sizeof(a); i++)
  694.     {
  695.         if (i != 0)
  696.             buf[i * 4 - 1] = '.';
  697.  
  698.         (void)sprintf(&buf[i * 4], "%03d", (a >> (24 - (i * 8))) & 0xFF);
  699.     }
  700.  
  701.     return &buf[0];
  702. }
  703.  
  704. static
  705. void
  706. vis_address(outfp, s)
  707. FILE        *outfp;
  708. struct sockaddr    *s;
  709. {
  710.     if (s->sa_family == AF_INET)
  711.     {
  712.         struct sockaddr_in    is;
  713.  
  714.         *(struct sockaddr_in *)&is = *(struct sockaddr_in *)s;
  715.         fprintf(outfp, "{");
  716.         fprintf(outfp, "port=%d,", is.sin_port);
  717.         fprintf(outfp, "addr=%s", say_addr(is.sin_addr.s_addr));
  718.         fprintf(outfp, "}");
  719.     }
  720.     else
  721.         vis_quoted_truncated_buffer(outfp, sizeof(s->sa_data), &s->sa_data[0], sizeof(s->sa_data));
  722. }
  723.  
  724. void
  725. say_time(outfp, t)
  726. FILE        *outfp;
  727. unsigned long    t;
  728. {
  729.     char    *cp;
  730.  
  731.     cp = ctime(&t);
  732.     cp[24] = '\0'; /* overwrite the newline */
  733.     fprintf(outfp, "%lu[%s]", t, cp);
  734. }
  735.  
  736. int
  737. printval(universe, arg, desc, args, return_value0, return_value1, direction)
  738. int    universe;
  739. long    arg;
  740. int    desc;
  741. long    *args;
  742. long    return_value0;
  743. long    return_value1;
  744. int    direction;
  745. {
  746.     int        length;
  747.     char        **app;
  748.     char        **cpp;
  749.     struct flock    sheep;
  750.  
  751.     switch (desc)
  752.     {
  753.     case 'A':    /* ioctl arg */
  754.         switch (universe)
  755.         {
  756.         case U_SYSV:
  757.             return sysv_print_ioctl_arg(args); 
  758.  
  759.         case U_BSD43:
  760.             return bsd43_print_ioctl_arg(args); 
  761.  
  762.         case U_POSIX:
  763.             return posix_print_ioctl_arg(args); 
  764.  
  765.         default:
  766.             vcouldnot("print ioctl arg from unknown universe %d", universe);
  767.             return -1;
  768.         }
  769.         break;
  770.  
  771.     case 'B':    /* fcntl cmd */
  772.         switch (arg)
  773.         {
  774.         case F_DUPFD:
  775.             fprintf(outfp, "F_DUPFD");
  776.             break;
  777.  
  778.         case F_GETFD:
  779.             fprintf(outfp, "F_GETFD");
  780.             break;
  781.  
  782.         case F_SETFD:
  783.             fprintf(outfp, "F_SETFD");
  784.             break;
  785.  
  786.         case F_GETFL:
  787.             fprintf(outfp, "F_GETFL");
  788.             break;
  789.  
  790.         case F_SETFL:
  791.             fprintf(outfp, "F_SETFL");
  792.             break;
  793.  
  794.         case F_GETLK:
  795.             fprintf(outfp, "F_GETLK");
  796.             break;
  797.  
  798.         case F_SETLK:
  799.             fprintf(outfp, "F_SETLK");
  800.             break;
  801.  
  802.         case F_SETLKW:
  803.             fprintf(outfp, "F_SETLKW");
  804.             break;
  805.  
  806.         case F_CHKFL:
  807.             fprintf(outfp, "F_CHKFL");
  808.             break;
  809.  
  810.         case F_GETOWN:
  811.             fprintf(outfp, "F_GETOWN");
  812.             break;
  813.  
  814.         case F_SETOWN:
  815.             fprintf(outfp, "F_SETOWN");
  816.             break;
  817.  
  818.         case PFCSEXEC:
  819.             fprintf(outfp, "PFCSEXEC");
  820.             break;
  821.  
  822.         case PFCREXEC:
  823.             fprintf(outfp, "PFCREXEC");
  824.             break;
  825.  
  826.         case PFCRUN:
  827.             fprintf(outfp, "PFCRUN");
  828.             break;
  829.  
  830.         case PFCSSTEP:
  831.             fprintf(outfp, "PFCSSTEP");
  832.             break;
  833.  
  834.         case PFCCSIG:
  835.             fprintf(outfp, "PFCCSIG");
  836.             break;
  837.  
  838.         case PFCWSTOP:
  839.             fprintf(outfp, "PFCWSTOP");
  840.             break;
  841.  
  842.         case PFCGMASK:
  843.             fprintf(outfp, "PFCGMASK");
  844.             break;
  845.  
  846.         case PFCSMASK:
  847.             fprintf(outfp, "PFCSMASK");
  848.             break;
  849.  
  850.         case PFCSTOP:
  851.             fprintf(outfp, "PFCSTOP");
  852.             break;
  853.  
  854.         case PFCGETPR:
  855.             fprintf(outfp, "PFCGETPR");
  856.             break;
  857.  
  858.         case PFCGETUSEG:
  859.             fprintf(outfp, "PFCGETUSEG");
  860.             break;
  861.  
  862.         case PFCGETREGS:
  863.             fprintf(outfp, "PFCGETREGS");
  864.             break;
  865.  
  866.         default:
  867.             fprintf(outfp, "0x%x", arg);
  868.             break;
  869.         }
  870.         break;
  871.  
  872.     case 'C':    /* ioctl cmd */
  873.         switch (universe)
  874.         {
  875.         case U_SYSV:
  876.             return sysv_print_ioctl_cmd(arg); 
  877.  
  878.         case U_BSD43:
  879.             return bsd43_print_ioctl_cmd(arg); 
  880.  
  881.         case U_POSIX:
  882.             return posix_print_ioctl_cmd(arg); 
  883.  
  884.         default:
  885.             vcouldnot("print ioctl cmd from unknown universe %d", universe);
  886.             return -1;
  887.         }
  888.         break;
  889.  
  890.     case 'D':    /* select fd_set */
  891.         switch (universe)
  892.         {
  893.         case U_SYSV:
  894.             return sysv_print_fdset(args[0], arg); 
  895.  
  896.         case U_BSD43:
  897.             return bsd43_print_fdset(args[0], arg); 
  898.  
  899.         case U_POSIX:
  900.             return posix_print_fdset(args[0], arg); 
  901.  
  902.         default:
  903.             vcouldnot("print fdset from unknown universe %d", universe);
  904.             return -1;
  905.         }
  906.         break;
  907.  
  908.     case 'E':    /* envp */
  909.         fprintf(outfp, "{");
  910.         if (Aflag)
  911.         {
  912.             if ((app = mgetvp(arg)) == (char **)0)
  913.                 return -1;
  914.  
  915.             for (cpp = app; *cpp != (char *)0; cpp++)
  916.             {
  917.                 vis_string_with_quotes(outfp, *cpp);
  918.                 fprintf(outfp, ",");
  919.             }
  920.  
  921.             if (mfreevp(app) == -1)
  922.                 return -1;
  923.         }
  924.         else
  925.             fprintf(outfp, "..");
  926.         fprintf(outfp, "}");
  927.         break;
  928.  
  929.     case 'F':    /* filename */
  930.         {
  931.             char    *cp;
  932.  
  933.             if (mgets(arg, &cp) == -1)
  934.                 return -1;
  935.  
  936.             vis_string_with_quotes(outfp, cp);
  937.         }
  938.         break;
  939.  
  940.     case 'G':    /* getgroups() group set */
  941.         fprintf(outfp, "{");
  942.         if (direction == DIRN_EXIT)
  943.         {
  944.             length = return_value0;
  945.  
  946.             if (length < 0)
  947.                 length = 0;
  948.  
  949.             if (bufset((unsigned int)length * sizeof(int)) == -1)
  950.                 return -1;
  951.  
  952.             if (quiet_procmget(GLOBALdipc, (unsigned long)arg, sys_call_buf, length * sizeof(int)) == -1)
  953.                 return -1;
  954.  
  955.             {
  956.                 int    i;
  957.  
  958.                 for (i = 0; i < length; i++)
  959.                     fprintf(outfp, "%d, ", ((int *)sys_call_buf)[i]);
  960.             }
  961.         }
  962.         fprintf(outfp, "}");
  963.         break;
  964.  
  965.     case 'H':    /* fcntl arg */
  966.         switch (args[1])
  967.         {
  968.         case F_DUPFD:
  969.         case F_GETFD:
  970.         case F_SETFD:
  971.         case F_GETFL:
  972.         case F_SETFL:
  973.             fprintf(outfp, "0x%x", arg);
  974.             break;
  975.  
  976.         case F_GETLK:
  977.         case F_SETLK:
  978.         case F_SETLKW:
  979.             if (quiet_procmget(GLOBALdipc, arg, (char *)&sheep, sizeof(sheep)) == -1)
  980.                 return -1;
  981.  
  982.             fprintf(outfp, "{");
  983.             fprintf(outfp, "type=");
  984.             switch (sheep.l_type)
  985.             {
  986.             case F_RDLCK:
  987.                 fprintf(outfp, "F_RDLCK");
  988.                 break;
  989.  
  990.             case F_WRLCK:
  991.                 fprintf(outfp, "F_WRLCK");
  992.                 break;
  993.  
  994.             case F_UNLCK:
  995.                 fprintf(outfp, "F_UNLCK");
  996.                 break;
  997.  
  998.             default:
  999.                 fprintf(outfp, "0x%x", sheep.l_type);
  1000.                 break;
  1001.             }
  1002.             fprintf(outfp, ",");
  1003.             fprintf(outfp, "whence=%d,", sheep.l_whence);
  1004.             fprintf(outfp, "start=%d,", sheep.l_start);
  1005.             fprintf(outfp, "len=%d,", sheep.l_len);
  1006.             fprintf(outfp, "sysid=%d,", sheep.l_sysid);
  1007.             fprintf(outfp, "pid=%d,", sheep.l_pid);
  1008.             fprintf(outfp, "}");
  1009.             break;
  1010.  
  1011.         default:
  1012.             fprintf(outfp, "0x%x", arg);
  1013.             break;
  1014.         }
  1015.         break;
  1016.  
  1017.  
  1018.     case 'I':    /* program address */
  1019.         fprintf(outfp, "%s", proc_text_address(arg));
  1020.         break;
  1021.  
  1022.     case 'J':    /* signal action or program address */
  1023.         switch (arg)
  1024.         {
  1025.         case SIG_ERR:
  1026.             fprintf(outfp, "SIG_ERR");
  1027.             break;
  1028.  
  1029.         case SIG_DFL:
  1030.             fprintf(outfp, "SIG_DFL");
  1031.             break;
  1032.  
  1033.         case SIG_IGN:
  1034.             fprintf(outfp, "SIG_IGN");
  1035.             break;
  1036.  
  1037.         case SIG_HOLD:
  1038.             fprintf(outfp, "SIG_HOLD");
  1039.             break;
  1040.  
  1041.         default:
  1042.             fprintf(outfp, "%s", proc_text_address(arg));
  1043.             break;
  1044.         }
  1045.         break;
  1046.  
  1047.     case 'K':    /* signal name */
  1048.         fprintf(outfp, "%s", signal_name(arg));
  1049.         break;
  1050.  
  1051.     case 'L':    /* struct sockaddr */
  1052.         if (arg == (unsigned long)0)
  1053.             fprintf(outfp, "0x%x", arg);
  1054.         else
  1055.         {
  1056.             struct sockaddr    s;
  1057.  
  1058.             if (quiet_procmget(GLOBALdipc, arg, (char *)&s, sizeof(s)) == -1)
  1059.                 return -1;
  1060.  
  1061.             fprintf(outfp, "{");
  1062.             fprintf(outfp, "family=%s,", say_family(s.sa_family));
  1063.             fprintf(outfp, "sa_data=");
  1064.             vis_address(outfp, &s);
  1065.             fprintf(outfp, "}");
  1066.         }
  1067.         break;
  1068.  
  1069.     case 'M':    /* signal set mask */
  1070.         fprintf(outfp, "%s", signal_set(arg));
  1071.         break;
  1072.  
  1073.     case 'N':    /* send()/recv() flags */
  1074.         if (arg == 0)
  1075.             fprintf(outfp, "0x0");
  1076.         else
  1077.         {
  1078.             int    need_bar;
  1079.  
  1080.             need_bar = 0;
  1081.             if (arg & MSG_OOB)
  1082.             {
  1083.                 fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_OOB");
  1084.                 need_bar = 1;
  1085.                 arg &= ~MSG_OOB;
  1086.             }
  1087.             if (arg & MSG_PEEK)
  1088.             {
  1089.                 fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_PEEK");
  1090.                 need_bar = 1;
  1091.                 arg &= ~MSG_PEEK;
  1092.             }
  1093.             if (arg & MSG_DONTROUTE)
  1094.             {
  1095.                 fprintf(outfp, "%s%s", need_bar ? "|" : "", "MSG_DONTROUTE");
  1096.                 need_bar = 1;
  1097.                 arg &= ~MSG_DONTROUTE;
  1098.             }
  1099.             if (arg)
  1100.                 fprintf(outfp, "%s0x%x", need_bar ? "|" : "", arg);
  1101.         }
  1102.         break;
  1103.  
  1104.     case 'O':    /* open flags */
  1105.         switch (universe)
  1106.         {
  1107.         case U_SYSV:
  1108.             return sysv_print_open_flags(arg); 
  1109.  
  1110.         case U_BSD43:
  1111.             return bsd43_print_open_flags(arg); 
  1112.  
  1113.         case U_POSIX:
  1114.             return posix_print_open_flags(arg); 
  1115.  
  1116.         default:
  1117.             vcouldnot("print open flags from unknown universe %d", universe);
  1118.             return -1;
  1119.         }
  1120.         break;
  1121.  
  1122.     case 'P':    /* access mode */
  1123.         if (arg == 0)
  1124.             fprintf(outfp, "F_OK");
  1125.         else
  1126.         {
  1127.             int    need_bar;
  1128.  
  1129.             need_bar = 0;
  1130.             if (arg & R_OK)
  1131.             {
  1132.                 fprintf(outfp, "%s%s", need_bar ? "|" : "", "R_OK");
  1133.                 need_bar = 1;
  1134.                 arg &= ~R_OK;
  1135.             }
  1136.             if (arg & W_OK)
  1137.             {
  1138.                 fprintf(outfp, "%s%s", need_bar ? "|" : "", "W_OK");
  1139.                 need_bar = 1;
  1140.                 arg &= ~W_OK;
  1141.             }
  1142.             if (arg & X_OK)
  1143.             {
  1144.                 fprintf(outfp, "%s%s", need_bar ? "|" : "", "X_OK");
  1145.                 need_bar = 1;
  1146.                 arg &= ~X_OK;
  1147.             }
  1148.             if (arg)
  1149.                 fprintf(outfp, "%s0x%x", need_bar ? "|" : "", arg);
  1150.         }
  1151.         break;
  1152.  
  1153.     case 'Q':    /* pair of int's (as in utime()) */
  1154.         if (arg == 0)
  1155.             fprintf(outfp, "0x%x", arg);
  1156.         else
  1157.         {
  1158.             int    i[2];
  1159.  
  1160.             if (quiet_procmget(GLOBALdipc, (unsigned long)arg, &i[0], sizeof(i)) == -1)
  1161.                 return -1;
  1162.  
  1163.             fprintf(outfp, "{");
  1164.             say_time(outfp, i[0]);
  1165.             fprintf(outfp, ",");
  1166.             say_time(outfp, i[1]);
  1167.             fprintf(outfp, "}");
  1168.         }
  1169.         break;
  1170.  
  1171.     case 'R':    /* read() buffer */
  1172.         if (direction == DIRN_ENTRY || args[0] == 100)
  1173.             fprintf(outfp, "\"\"");
  1174.         else
  1175.         {
  1176.             char    *cp;
  1177.  
  1178.             length = return_value0;
  1179.  
  1180.             if (length < 0)
  1181.                 length = 0;
  1182.             else if (Aflag == 0 && length > TRUNCATED_READ_WRITE_LENGTH)
  1183.                 length = TRUNCATED_READ_WRITE_LENGTH;
  1184.  
  1185.             if (dmget((unsigned long)arg, length, &cp) == -1)
  1186.                 return -1;
  1187.  
  1188.             vis_quoted_truncated_buffer(outfp, length, cp, return_value0);
  1189.         }
  1190.         break;
  1191.  
  1192.     case 'S':    /* struct stat */
  1193.         if (direction == DIRN_EXIT)
  1194.         {
  1195.             switch (universe)
  1196.             {
  1197.             case U_SYSV:
  1198.                 return sysv_print_stat(arg); 
  1199.  
  1200.             case U_BSD43:
  1201.                 return bsd43_print_stat(arg); 
  1202.  
  1203.             case U_POSIX:
  1204.                 return posix_print_stat(arg); 
  1205.  
  1206.             default:
  1207.                 vcouldnot("print stat structure from unknown universe %d", universe);
  1208.                 return -1;
  1209.             }
  1210.         }
  1211.         break;
  1212.  
  1213.     case 'T':    /* struct timeval */
  1214.         if (arg == (unsigned long)0)
  1215.             fprintf(outfp, "0x%x", arg);
  1216.         else
  1217.         {
  1218.             struct timeval    t;
  1219.  
  1220.             if (quiet_procmget(GLOBALdipc, arg, (char *)&t, sizeof(t)) == -1)
  1221.                 return -1;
  1222.  
  1223.             fprintf(outfp, "{");
  1224.             fprintf(outfp, "sec=%d,", t.tv_sec);
  1225.             fprintf(outfp, "usec=%d", t.tv_usec);
  1226.             fprintf(outfp, "}");
  1227.         }
  1228.         break;
  1229.  
  1230.     case 'U':    /* pointer to an int */
  1231.         if (arg == (unsigned long)0)
  1232.             fprintf(outfp, "0x%x", arg);
  1233.         else
  1234.         {
  1235.             int    i;
  1236.  
  1237.             if (quiet_procmget(GLOBALdipc, arg, (char *)&i, sizeof(i)) == -1)
  1238.                 return -1;
  1239.  
  1240.             fprintf(outfp, "{%d}", i);
  1241.         }
  1242.         break;
  1243.  
  1244.     case 'V':    /* pair of struct timeval's */
  1245.         if (arg == (unsigned long)0)
  1246.             fprintf(outfp, "0x%x", arg);
  1247.         else
  1248.         {
  1249.             struct timeval    t[2];
  1250.  
  1251.             if (quiet_procmget(GLOBALdipc, arg, &t[0], sizeof(t)) == -1)
  1252.                 return -1;
  1253.  
  1254.             fprintf(outfp, "{");
  1255.             fprintf(outfp, "{");
  1256.             fprintf(outfp, "sec=%d,", t[0].tv_sec);
  1257.             fprintf(outfp, "usec=%d", t[0].tv_usec);
  1258.             fprintf(outfp, "}");
  1259.             fprintf(outfp, "{");
  1260.             fprintf(outfp, "sec=%d,", t[1].tv_sec);
  1261.             fprintf(outfp, "usec=%d", t[1].tv_usec);
  1262.             fprintf(outfp, "}");
  1263.             fprintf(outfp, "}");
  1264.         }
  1265.         break;
  1266.  
  1267.     case 'W':    /* write() buffer */
  1268.         {
  1269.             char    *cp;
  1270.  
  1271.             length = args[2];
  1272.  
  1273.             if (Aflag == 0 && length > TRUNCATED_READ_WRITE_LENGTH)
  1274.                 length = TRUNCATED_READ_WRITE_LENGTH;
  1275.  
  1276.             if (dmget((unsigned long)arg, length, &cp) == -1)
  1277.                 return -1;
  1278.  
  1279.             vis_quoted_truncated_buffer(outfp, length, cp, args[2]);
  1280.         }
  1281.         break;
  1282.  
  1283.     case 'X':    /* struct statfs */
  1284.         switch (universe)
  1285.         {
  1286.         case U_SYSV:
  1287.             return sysv_print_statfs(arg); 
  1288.  
  1289.         case U_BSD43:
  1290.             return bsd43_print_statfs(arg); 
  1291.  
  1292.         case U_POSIX:
  1293.             return posix_print_statfs(arg); 
  1294.  
  1295.         default:
  1296.             vcouldnot("print statfs structure from unknown universe %d", universe);
  1297.             return -1;
  1298.         }
  1299.         break;
  1300.  
  1301.     case 'Y':    /* result pair */
  1302.         fprintf(outfp, "{%d,%d}", return_value0, return_value1);
  1303.         break;
  1304.  
  1305.     case 'Z':    /* struct timezone */
  1306.         if (arg == (unsigned long)0)
  1307.             fprintf(outfp, "0x%x", arg);
  1308.         else
  1309.         {
  1310.             struct timezone    t;
  1311.  
  1312.             if (quiet_procmget(GLOBALdipc, arg, (char *)&t, sizeof(t)) == -1)
  1313.                 return -1;
  1314.  
  1315.             fprintf(outfp, "{");
  1316.             fprintf(outfp, "minuteswest=%d,", t.tz_minuteswest);
  1317.             fprintf(outfp, "dsttime=%d", t.tz_dsttime);
  1318.             fprintf(outfp, "}");
  1319.         }
  1320.         break;
  1321.  
  1322.     case 'a':    /* socket domain */
  1323.         switch (arg)
  1324.         {
  1325.         case PF_UNIX:
  1326.             fprintf(outfp, "PF_UNIX");
  1327.             break;
  1328.  
  1329.         case PF_INET:
  1330.             fprintf(outfp, "PF_INET");
  1331.             break;
  1332.  
  1333.         case PF_NS:
  1334.             fprintf(outfp, "PF_NS");
  1335.             break;
  1336.  
  1337.         case PF_IMPLINK:
  1338.             fprintf(outfp, "PF_IMPLINK");
  1339.             break;
  1340.  
  1341.         default:
  1342.             fprintf(outfp, "%d", arg);
  1343.             break;
  1344.         }
  1345.         break;
  1346.  
  1347.     case 'b':    /* socket type */
  1348.         switch (arg)
  1349.         {
  1350.         case SOCK_STREAM:
  1351.             fprintf(outfp, "SOCK_STREAM");
  1352.             break;
  1353.  
  1354.         case SOCK_DGRAM:
  1355.             fprintf(outfp, "SOCK_DGRAM");
  1356.             break;
  1357.  
  1358.         case SOCK_RAW:
  1359.             fprintf(outfp, "SOCK_RAW");
  1360.             break;
  1361.  
  1362.         case SOCK_SEQPACKET:
  1363.             fprintf(outfp, "SOCK_SEQPACKET");
  1364.             break;
  1365.  
  1366.         case SOCK_RDM:
  1367.             fprintf(outfp, "SOCK_RDM");
  1368.             break;
  1369.  
  1370.         default:
  1371.             fprintf(outfp, "%d", arg);
  1372.             break;
  1373.         }
  1374.         break;
  1375.  
  1376.     case 'c':    /* socket protocol */
  1377.         {
  1378.             struct protoent    *p;
  1379.  
  1380.             if
  1381.             (
  1382.                 args[0] == PF_INET
  1383.                 &&
  1384.                 (p = getprotobynumber(arg)) != (struct protoent *)0
  1385.             )
  1386.                 fprintf(outfp, "%s", p->p_name);
  1387.             else
  1388.                 fprintf(outfp, "%d", arg);
  1389.         }
  1390.         break;
  1391.  
  1392.     case 'd':    /* int */
  1393.         fprintf(outfp, "%d", arg);
  1394.         break;
  1395.  
  1396.     case 'e':    /* int -- result from execve()/exit() see i_syscall() */
  1397.         fprintf(outfp, "%d", arg);
  1398.         break;
  1399.  
  1400.     case 'f':    /* pointer to a struct sigvec */
  1401.         if (bsd43_print_sigvec(arg) == -1)
  1402.             return -1;
  1403.         break;
  1404.  
  1405.     case 'g':    /* setgroups() group set */
  1406.         fprintf(outfp, "{");
  1407.         {
  1408.             length = args[0];
  1409.  
  1410.             if (length < 0)
  1411.                 length = 0;
  1412.  
  1413.             if (bufset((unsigned int)length * sizeof(int)) == -1)
  1414.                 return -1;
  1415.  
  1416.             if (quiet_procmget(GLOBALdipc, (unsigned long)arg, sys_call_buf, length * sizeof(int)) == -1)
  1417.                 return -1;
  1418.  
  1419.             {
  1420.                 int    i;
  1421.  
  1422.                 for (i = 0; i < length; i++)
  1423.                     fprintf(outfp, "%d, ", ((int *)sys_call_buf)[i]);
  1424.             }
  1425.         }
  1426.         fprintf(outfp, "}");
  1427.         break;
  1428.  
  1429.     case 'h':    /* wait3 union wait */
  1430.         if (sysv_print_wait3_union_wait(arg) == -1)
  1431.             return -1;
  1432.         break;
  1433.  
  1434.     case 'i':    /* wait3 options */
  1435.         if (sysv_print_wait3_options(arg) == -1)
  1436.             return -1;
  1437.         break;
  1438.  
  1439.     case 'j':    /* wait3 rusage */
  1440.         if (sysv_print_wait3_rusage(arg) == -1)
  1441.             return -1;
  1442.         break;
  1443.  
  1444.     case 'k':    /* times tms */
  1445.         {
  1446.             struct tms    t;
  1447.             struct tms    *tp;
  1448.  
  1449.             if (mget(arg, &t, sizeof(t), &tp) == -1)
  1450.                 return -1;
  1451.  
  1452.             if (tp == (struct tms *)0)
  1453.                 fprintf(outfp, "0x%x", arg);
  1454.             else
  1455.             {
  1456.                 fprintf(outfp, "{" /* } */);
  1457.  
  1458.                 fprintf(outfp, "utime=%d,", t.tms_utime);
  1459.                 fprintf(outfp, "stime=%d,", t.tms_stime);
  1460.                 fprintf(outfp, "cutime=%d,", t.tms_cutime);
  1461.                 fprintf(outfp, "cstime=%d,", t.tms_cstime);
  1462.  
  1463.                 fprintf(outfp, /* { */ "}");
  1464.             }
  1465.  
  1466.             return 0;
  1467.         }
  1468.         break;
  1469.  
  1470.     case 'l':    /* argp */
  1471.         fprintf(outfp, "{");
  1472.         if (Aflag)
  1473.         {
  1474.             if ((app = mgetvp(arg)) == (char **)0)
  1475.                 return -1;
  1476.  
  1477.             for (cpp = app; *cpp != (char *)0; cpp++)
  1478.             {
  1479.                 vis_string_with_quotes(outfp, *cpp);
  1480.                 fprintf(outfp, ",");
  1481.             }
  1482.  
  1483.             if (mfreevp(app) == -1)
  1484.                 return -1;
  1485.         }
  1486.         else
  1487.             fprintf(outfp, "..");
  1488.         fprintf(outfp, "}");
  1489.         break;
  1490.  
  1491.     case 'm':    /* file creation mode */
  1492.         fprintf(outfp, "%s%o", (arg == 0) ? "" : "0", arg);
  1493.         break;
  1494.  
  1495.     case 'o':    /* octal int */
  1496.         fprintf(outfp, "%s%o", (arg == 0) ? "" : "0", arg);
  1497.         break;
  1498.  
  1499.     case 'p':    /* pointer */
  1500.     case 'x':    /* " */
  1501.         fprintf(outfp, "0x%x", arg);
  1502.         break;
  1503.  
  1504.     case 's':    /* outgoing string */
  1505.         if (direction == DIRN_EXIT)
  1506.         {
  1507.             char    *cp;
  1508.  
  1509.             if (mgets(arg, &cp) == -1)
  1510.                 return -1;
  1511.  
  1512.             vis_string_with_quotes(outfp, cp);
  1513.         }
  1514.         break;
  1515.  
  1516.     case 't':    /* time_t */
  1517.         say_time(outfp, arg);
  1518.         break;
  1519.  
  1520.     case 'u':    /* unsigned long */
  1521.         fprintf(outfp, "%lu", arg);
  1522.         break;
  1523.  
  1524.     case 'v':    /* pointer to a time_t */
  1525.         if (arg == (unsigned long)0)
  1526.             fprintf(outfp, "0x%x", arg);
  1527.         else
  1528.         {
  1529.             long    i;
  1530.  
  1531.             if (quiet_procmget(GLOBALdipc, arg, (char *)&i, sizeof(i)) == -1)
  1532.                 return -1;
  1533.  
  1534.             fprintf(outfp, "{");
  1535.             say_time(outfp, i);
  1536.             fprintf(outfp, "}");
  1537.         }
  1538.         break;
  1539.  
  1540.     case 'w':    /* lseek() whence */
  1541.         switch (universe)
  1542.         {
  1543.         case U_SYSV:
  1544.             return sysv_print_whence(arg); 
  1545.  
  1546.         case U_BSD43:
  1547.             return bsd43_print_whence(arg); 
  1548.  
  1549.         case U_POSIX:
  1550.             return posix_print_whence(arg); 
  1551.  
  1552.         default:
  1553.             vcouldnot("print whence from unknown universe %d", universe);
  1554.             return -1;
  1555.         }
  1556.         break;
  1557.  
  1558.     case 'y':    /* sigcontext */
  1559.         switch (universe)
  1560.         {
  1561.         case U_SYSV:
  1562.             return sysv_print_sigcontext(outfp, arg);
  1563.  
  1564.         case U_BSD43:
  1565.             return bsd43_print_sigcontext(outfp, arg);
  1566.  
  1567.         case U_POSIX:
  1568.             return posix_print_sigcontext(outfp, arg);
  1569.  
  1570.         default:
  1571.             vcouldnot("print sigcontext from unknown universe %d", universe);
  1572.             return -1;
  1573.         }
  1574.         break;
  1575.  
  1576.     case '\0':    /* unknown */
  1577.     default:    /* " */
  1578.         fprintf(outfp, "0x%x", arg);
  1579.         break;
  1580.     }
  1581.  
  1582.     return 0;
  1583. }
  1584.  
  1585. static
  1586. char    *
  1587. say_errno(e)
  1588. int    e;
  1589. {
  1590.     if (e < 0 || e >= sys_nerrno)
  1591.         e = 0;
  1592.  
  1593.     return sys_errnolist[e];
  1594. }
  1595.  
  1596. static
  1597. int
  1598. show_syscall(universe, universe_name, current_sysentp, argp, return_value0, return_value1, return_errno, direction)
  1599. int        universe;
  1600. char        *universe_name;
  1601. sysentry    *current_sysentp;
  1602. unsigned long    *argp;
  1603. long        return_value0;
  1604. long        return_value1;
  1605. int        return_errno;
  1606. int        direction;
  1607. {
  1608.     int    i;
  1609.  
  1610.     fprintf(outfp, "%6d:", P.p_pid);
  1611.  
  1612.     fprintf(outfp, "%s_", universe_name);
  1613.  
  1614.     fprintf(outfp, "%s(", (current_sysentp->sy_name == (char *)0) ? "<unknown>" : current_sysentp->sy_name);
  1615.  
  1616.     for (i = 0; i < current_sysentp->sy_narg; i++)
  1617.     {
  1618.         if (i != 0)
  1619.             fprintf(outfp, ", ");
  1620.         if (printval(universe, argp[i], (int)current_sysentp->sy_desc[i], argp, return_value0, return_value1, direction) == -1)
  1621.             return -1;
  1622.     }
  1623.  
  1624.     fprintf(outfp, ")");
  1625.  
  1626.     if (direction == DIRN_EXIT)
  1627.     {
  1628.         fprintf(outfp, " = ");
  1629.  
  1630.         if (printval(universe, return_value0, (int)current_sysentp->sy_rdesc, argp, return_value0, return_value1, direction) == -1)
  1631.             return -1;
  1632.  
  1633.         if (return_errno != 0)
  1634.         {
  1635.             int    saved_errno;
  1636.  
  1637.             saved_errno = errno;
  1638.             errno = return_errno;
  1639.             fprintf(outfp, " %s (%s)", say_errno(return_errno), sysmess());
  1640.             errno = saved_errno;
  1641.         }
  1642.     }
  1643.  
  1644.     if (Nflag)
  1645.     {
  1646.         fprintf(outfp, " [%d,%d]", instruction_count_since_last_syscall, instruction_count);
  1647.         instruction_count_since_last_syscall = 0;
  1648.     }
  1649.  
  1650.     if (Tflag)
  1651.         res_print();
  1652.  
  1653.     fprintf(outfp, "\n");
  1654.  
  1655.     return 0;
  1656. }
  1657.  
  1658. dinstrn    *
  1659. i_syscall(dipc, rs, rt, rd, shamt, funct)
  1660. dinstrn    *dipc;
  1661. int    rs;
  1662. int    rt;
  1663. int    rd;
  1664. int    shamt;
  1665. int    funct;
  1666. {
  1667.     int        stacki;
  1668.     unsigned long    real_syscall_number;
  1669.     int        syscall_number;
  1670.     int        universe;
  1671.     char        *universe_name;
  1672.     int        argi;
  1673.     int        r;
  1674.     int        (*fp)();
  1675.  
  1676.     errno = 0;
  1677.  
  1678.     stacki = 0;
  1679.  
  1680.     current_sysentp = (sysentry *)0;
  1681.     universe_name = "<unknown universe>";
  1682.  
  1683.     GLOBALdipc = dipc;
  1684.  
  1685.     /*
  1686.      * Determine the system call number,
  1687.      * doing any indirection as required.
  1688.      */
  1689.     for (;;)
  1690.     {
  1691.         if (get_syscall_arg(stacki++, &real_syscall_number) == -1)
  1692.             return dipc;
  1693.  
  1694.         syscall_number = real_syscall_number % 1000;
  1695.  
  1696.         /*
  1697.          * This next test should really refer to
  1698.          *    SYS_syscall
  1699.          *    BSD43_SYS_syscall
  1700.          *    POSIX_SYS_syscall
  1701.          * but the latter exists instead as
  1702.          *    SYS_syscall
  1703.          * which would cause an embarrassing
  1704.          * name clash.
  1705.          * They all expand to 0 anyway,
  1706.          * so that's what we use.
  1707.          */
  1708.         if (syscall_number == 0)
  1709.             continue;
  1710.  
  1711.         switch (universe = real_syscall_number / 1000)
  1712.         {
  1713.         case U_SYSV:
  1714.             universe_name = "sysv";
  1715.             current_sysentp = sysv_systab_entry(syscall_number);
  1716.             break;
  1717.  
  1718.         case U_BSD43:
  1719.             universe_name = "bsd43";
  1720.             current_sysentp = bsd43_systab_entry(syscall_number);
  1721.             break;
  1722.  
  1723.         case U_POSIX:
  1724.             universe_name = "posix";
  1725.             current_sysentp = posix_systab_entry(syscall_number);
  1726.             break;
  1727.  
  1728.         case 0:
  1729.         default:
  1730.             break;
  1731.         }
  1732.  
  1733.         break;
  1734.     }
  1735.  
  1736.     if (current_sysentp == (sysentry *)0)
  1737.     {
  1738.         vcouldnot("execute unimplemented %s system call #%d", universe_name, real_syscall_number);
  1739.         return dipc;
  1740.     }
  1741.  
  1742.     if ((fp = current_sysentp->sy_call) == (int (*)())0)
  1743.     {
  1744.         vcouldnot("execute unimplemented %s system call \"%s\" [#%d]", universe_name, (current_sysentp->sy_name == (char *)0) ? "" : current_sysentp->sy_name, real_syscall_number);
  1745.         return dipc;
  1746.     }
  1747.  
  1748.     /*
  1749.      * Get the system call's arguments.
  1750.      */
  1751.     for (argi = 0; argi < current_sysentp->sy_narg; argi++)
  1752.     {
  1753.         if (get_syscall_arg(stacki++, &arg[argi]) == -1)
  1754.             return dipc;
  1755.     }
  1756.  
  1757.     /*
  1758.      * Print system call arguments before execution if desired.
  1759.      * (The 'e' kludge is for execve() and exit()...)
  1760.      */
  1761.     if (Pflag || (Sflag && current_sysentp->sy_rdesc == 'e'))
  1762.     {
  1763.         if (show_syscall(universe, universe_name, current_sysentp, &arg[0], (long)0, (long)0, 0, DIRN_ENTRY) == -1)
  1764.             return dipc;
  1765.     }
  1766.  
  1767.     /*
  1768.      * Run the system call.
  1769.      */
  1770.     switch (r = (*fp)(real_syscall_number))
  1771.     {
  1772.     case 0:        /* OK */
  1773.         dipc = GLOBALdipc;
  1774.         break;
  1775.  
  1776.     case -1:    /* Some internal error. */
  1777.         dipc = GLOBALdipc;
  1778.         return dipc;
  1779.  
  1780.     case -2:    /* Unimpl. feature. */
  1781.         dipc = GLOBALdipc;
  1782.         if (!Pflag && !(Sflag && current_sysentp->sy_rdesc == 'e'))
  1783.         {
  1784.             if (show_syscall(universe, universe_name, current_sysentp, &arg[0], (long)0, (long)0, 0, DIRN_ENTRY) == -1)
  1785.                 return dipc;
  1786.         }
  1787.  
  1788.         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);
  1789.         return dipc;
  1790.  
  1791.     case -3:    /* OK, but don't copy errno/values to registers. */
  1792.         dipc = GLOBALdipc;
  1793.         break;
  1794.  
  1795.     default:    /* Somebody stuffed up ... */
  1796.         dipc = GLOBALdipc;
  1797.         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);
  1798.         return dipc;
  1799.     }
  1800.  
  1801.     if (r != -3)
  1802.     {
  1803.         /*
  1804.          * Pass back errno and return values.
  1805.          */
  1806.         if (return_errno == 0)
  1807.         {
  1808.             if (quiet_procsput(R_V0, (unsigned long)return_value0) == -1)
  1809.                 return dipc;
  1810.  
  1811.             if (quiet_procsput(R_V1, (unsigned long)return_value1) == -1)
  1812.                 return dipc;
  1813.  
  1814.             if (quiet_procsput(R_A3, 0) == -1)
  1815.                 return dipc;
  1816.         }
  1817.         else
  1818.         {
  1819.             if (quiet_procsput(R_V0, (unsigned long)return_errno) == -1)
  1820.                 return dipc;
  1821.  
  1822.             if (quiet_procsput(R_A3, 1) == -1)
  1823.                 return dipc;
  1824.         }
  1825.     }
  1826.  
  1827.     /*
  1828.      * Print system call arguments and results
  1829.      * after execution if desired.
  1830.      */
  1831.     if (Sflag)
  1832.     {
  1833.         if (show_syscall(universe, universe_name, current_sysentp, &arg[0], return_value0, return_value1, return_errno, DIRN_EXIT) == -1)
  1834.             return dipc;
  1835.     }
  1836.  
  1837.     return dipc;
  1838. }
  1839.