home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / d / strace / strace-3.000 / strace-3 / strace-3.0 / desc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-21  |  7.8 KB  |  375 lines

  1. /*
  2.  * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
  3.  * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  4.  * Copyright (c) 1993, 1994 Rick Sladkey <jrs@world.std.com>
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in the
  14.  *    documentation and/or other materials provided with the distribution.
  15.  * 3. All advertising materials mentioning features or use of this software
  16.  *    must display the following acknowledgement:
  17.  *      This product includes software developed by Paul Kranenburg,
  18.  *      Branko Lankester and Rick Sladkey.
  19.  * 4. The name of the author may not be used to endorse or promote products
  20.  *    derived from this software without specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  23.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  24.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  25.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  26.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  27.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  28.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  29.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  31.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32.  *
  33.  *    desc.c,v 2.21 1994/03/21 05:45:26 jrs Exp
  34.  */
  35.  
  36. #include "defs.h"
  37.  
  38. #include <fcntl.h>
  39. #include <sys/file.h>
  40.  
  41. static struct xlat fcntlcmds[] = {
  42.     { F_DUPFD,    "F_DUPFD"    },
  43.     { F_GETFD,    "F_GETFD"    },
  44.     { F_SETFD,    "F_SETFD"    },
  45.     { F_GETFL,    "F_GETFL"    },
  46.     { F_SETFL,    "F_SETFL"    },
  47.     { F_GETLK,    "F_GETLK"    },
  48.     { F_SETLK,    "F_SETLK"    },
  49.     { F_SETLKW,    "F_SETLKW"    },
  50.     { F_GETOWN,    "F_GETOWN"    },
  51.     { F_SETOWN,    "F_SETOWN"    },
  52. #ifdef F_RSETLK
  53.     { F_RSETLK,    "F_RSETLK"    },
  54. #endif
  55. #ifdef F_RSETLKW
  56.     { F_RSETLKW,    "F_RSETLKW"    },
  57. #endif
  58. #ifdef F_RGETLK
  59.     { F_RGETLK,    "F_RGETLK"    },
  60. #endif
  61. #ifdef F_CNVT
  62.     { F_CNVT,    "F_CNVT"    },
  63. #endif
  64.     { 0,        NULL        },
  65. };
  66.  
  67. static struct xlat fdflags[] = {
  68. #ifdef FD_CLOEXEC
  69.     { FD_CLOEXEC,    "FD_CLOEXEC"    },
  70. #endif
  71.     { 0,        NULL        },
  72. };
  73.  
  74. #ifdef SUNOS4
  75.  
  76. static struct xlat flockcmds[] = {
  77.     { LOCK_SH,    "LOCK_SH"    },
  78.     { LOCK_EX,    "LOCK_EX"    },
  79.     { LOCK_NB,    "LOCK_NB"    },
  80.     { LOCK_UN,    "LOCK_UN"    },
  81.     { 0,        NULL        },
  82. };
  83.  
  84. #endif
  85.  
  86. static struct xlat lockfcmds[] = {
  87.     { F_RDLCK,    "F_RDLCK"    },
  88.     { F_WRLCK,    "F_WRLCK"    },
  89.     { F_UNLCK,    "F_UNLCK"    },
  90. #ifdef F_EXLCK
  91.     { F_EXLCK,    "F_EXLCK"    },
  92. #endif
  93. #ifdef F_SHLCK
  94.     { F_SHLCK,    "F_SHLCK"    },
  95. #endif
  96.     { 0,        NULL        },
  97. };
  98.  
  99. static struct xlat whence[] = {
  100.     { SEEK_SET,    "SEEK_SET"    },
  101.     { SEEK_CUR,    "SEEK_CUR"    },
  102.     { SEEK_END,    "SEEK_END"    },
  103.     { 0,        NULL        },
  104. };
  105.  
  106. /* fcntl/lockf */
  107. static void
  108. printflock(tcp, addr, getlk)
  109. struct tcb *tcp;
  110. int addr;
  111. int getlk;
  112. {
  113.     struct flock fl;
  114.  
  115.     if (umove(tcp, addr, &fl) < 0) {
  116.         tprintf("{...}");
  117.         return;
  118.     }
  119.     tprintf("{type=");
  120.     printxval(lockfcmds, fl.l_type, "F_???");
  121.     tprintf(", whence=");
  122.     printxval(whence, fl.l_whence, "SEEK_???");
  123.     tprintf(", start=%ld, len=%ld", fl.l_start, fl.l_len);
  124.     if (getlk)
  125.         tprintf(", pid=%lu}", (unsigned long) fl.l_pid);
  126.     else
  127.         tprintf("}");
  128. }
  129.  
  130. static char *
  131. sprintflags(xlat, flags)
  132. struct xlat *xlat;
  133. int flags;
  134. {
  135.     static char outstr[1024];
  136.     char *sep;
  137.  
  138.     strcpy(outstr, "flags ");
  139.     sep = "";
  140.     for (; xlat->str; xlat++) {
  141.         if ((flags & xlat->val) == xlat->val) {
  142.             sprintf(outstr + strlen(outstr),
  143.                 "%s%s", sep, xlat->str);
  144.             sep = "|";
  145.             flags &= ~xlat->val;
  146.         }
  147.     }
  148.     if (flags)
  149.         sprintf(outstr + strlen(outstr),
  150.             "%s%#x", sep, flags);
  151.     return outstr;
  152. }
  153.  
  154. int
  155. sys_fcntl(tcp)
  156. struct tcb *tcp;
  157. {
  158.     extern struct xlat openmodes[];
  159.  
  160.     if (entering(tcp)) {
  161.         tprintf("%d, ", tcp->u_arg[0]);
  162.         printxval(fcntlcmds, tcp->u_arg[1], "F_???");
  163.         switch (tcp->u_arg[1]) {
  164.         case F_SETFD:
  165.             tprintf(", ");
  166.             if (printflags(fdflags, tcp->u_arg[2]) == 0)
  167.                 tprintf("0");
  168.             break;
  169.         case F_SETOWN: case F_DUPFD:
  170.             tprintf(", %d", tcp->u_arg[2]);
  171.             break;
  172.         case F_SETFL:
  173.             tprintf(", ");
  174.             if (printflags(openmodes, tcp->u_arg[2] + 1) == 0)
  175.                 tprintf("0");
  176.             break;
  177.         case F_SETLK: case F_SETLKW:
  178.             tprintf(", ");
  179.             printflock(tcp, tcp->u_arg[2], 0);
  180.             break;
  181.         }
  182.     }
  183.     else {
  184.         switch (tcp->u_arg[1]) {
  185.         case F_DUPFD:
  186.         case F_SETFD: case F_SETFL:
  187.         case F_SETLK: case F_SETLKW:
  188.         case F_SETOWN: case F_GETOWN:
  189.             break;
  190.         case F_GETFD:
  191.             if (tcp->u_rval == 0)
  192.                 return 0;
  193.             tcp->auxstr = sprintflags(fdflags, tcp->u_rval);
  194.             return RVAL_HEX|RVAL_STR;
  195.         case F_GETFL:
  196.             tcp->auxstr = sprintflags(openmodes, tcp->u_rval + 1);
  197.             return RVAL_HEX|RVAL_STR;
  198.         case F_GETLK:
  199.             tprintf(", ");
  200.             printflock(tcp, tcp->u_arg[2], 1);
  201.             break;
  202.         default:
  203.             tprintf(", %#x", tcp->u_arg[2]);
  204.             break;
  205.         }
  206.     }
  207.     return 0;
  208. }
  209.  
  210. #ifdef SUNOS4
  211. int
  212. sys_flock(tcp)
  213. struct tcb *tcp;
  214. {
  215.     if (entering(tcp)) {
  216.         tprintf("%d, ", tcp->u_arg[0]);
  217.         if (!printflags(flockcmds, tcp->u_arg[1]))
  218.             tprintf("LOCK_???");
  219.     }
  220.     return 0;
  221. }
  222. #endif /* SUNOS4 */
  223.  
  224. int
  225. sys_close(tcp)
  226. struct tcb *tcp;
  227. {
  228.     if (entering(tcp)) {
  229.         tprintf("%d", tcp->u_arg[0]);
  230.     }
  231.     return 0;
  232. }
  233.  
  234. int
  235. sys_dup(tcp)
  236. struct tcb *tcp;
  237. {
  238.     if (entering(tcp)) {
  239.         tprintf("%d", tcp->u_arg[0]);
  240.     }
  241.     return 0;
  242. }
  243.  
  244. int
  245. sys_dup2(tcp)
  246. struct tcb *tcp;
  247. {
  248.     if (entering(tcp)) {
  249.         tprintf("%d, %d", tcp->u_arg[0], tcp->u_arg[1]);
  250.     }
  251.     return 0;
  252. }
  253.  
  254. int
  255. sys_getdtablesize(tcp)
  256. struct tcb *tcp;
  257. {
  258.     return 0;
  259. }
  260.  
  261. int
  262. sys_select(tcp)
  263. struct tcb *tcp;
  264. {
  265.     int i, j, nfds;
  266.     fd_set fds;
  267.     struct timeval tv;
  268.     static char outstr[1024];
  269.     char *sep;
  270.     int arg;
  271. #ifdef LINUX
  272.     int args[5];
  273.     if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
  274.         tprintf("[...]");
  275.         return 0;
  276.     }
  277. #else /* !LINUX */
  278.     int *args = tcp->u_arg;
  279. #endif /* !LINUX */
  280.  
  281.     if (entering(tcp)) {
  282.         nfds = args[0];
  283.         tprintf("%d", nfds);
  284.         for (i = 0; i < 3; i++) {
  285.             arg = args[i+1];
  286.             if (arg == 0) {
  287.                 tprintf(", NULL");
  288.                 continue;
  289.             }
  290.             if (!verbose(tcp)) {
  291.                 tprintf(", %#x", arg);
  292.                 continue;
  293.             }
  294.             if (umove(tcp, arg, &fds) < 0) {
  295.                 tprintf(", [?]");
  296.                 continue;
  297.             }
  298.             tprintf(", [");
  299.             for (j = 0, sep = ""; j < nfds; j++) {
  300.                 if (FD_ISSET(j, &fds)) {
  301.                     tprintf("%s%u", sep, j);
  302.                     sep = " ";
  303.                 }
  304.             }
  305.             tprintf("]");
  306.         }
  307.         if (!args[4])
  308.             tprintf(", NULL");
  309.         else if (!verbose(tcp))
  310.             tprintf(", %#x", args[4]);
  311.         else if (umove(tcp, args[4], &tv) < 0)
  312.             tprintf(", {...}");
  313.         else
  314.             tprintf(", {%lu, %lu}", tv.tv_sec, tv.tv_usec);
  315.     }
  316.     else {
  317.         int cumlen = 0;
  318.         char *sep = "";
  319.  
  320.         if (syserror(tcp))
  321.             return 0;
  322.  
  323.         if ((nfds = tcp->u_rval) == 0) {
  324.             tcp->auxstr = "Timeout";
  325.             return RVAL_STR;
  326.         }
  327.         outstr[0] = '\0';
  328.         for (i = 0; i < 3; i++) {
  329.             int first = 1;
  330.             char str[20];
  331.  
  332.             tcp->auxstr = outstr;
  333.             arg = args[i+1];
  334.             if (!arg || umove(tcp, arg, &fds) < 0)
  335.                 continue;
  336.             for (j = 0; j < args[0]; j++) {
  337.                 if (FD_ISSET(j, &fds)) {
  338.                     if (first) {
  339.                         sprintf(str, "%s%s [%u", sep,
  340.                             i == 0 ? "in" :
  341.                             i == 1 ? "out" :
  342.                             "except", j);
  343.                         first = 0;
  344.                         sep = ", ";
  345.                     }
  346.                     else
  347.                         sprintf(str, " %u", j);
  348.                     cumlen += strlen(str);
  349.                     if (cumlen < sizeof outstr)
  350.                         strcat(outstr, str);
  351.                     nfds--;
  352.                 }
  353.             }
  354.             if (cumlen)
  355.                 strcat(outstr, "]");
  356.             if (nfds == 0)
  357.                 break;
  358.         }
  359. #ifdef LINUX
  360.         /* This contains no useful information on SunOS.  */
  361.         if (args[4]) {
  362.             char str[20];
  363.  
  364.             if (umove(tcp, args[4], &tv) >= 0)
  365.                 sprintf(str, "%sleft {%lu, %lu}", sep,
  366.                     tv.tv_sec, tv.tv_usec);
  367.             if ((cumlen += strlen(str)) < sizeof outstr)
  368.                 strcat(outstr, str);
  369.         }
  370. #endif /* LINUX */
  371.         return RVAL_STR;
  372.     }
  373.     return 0;
  374. }
  375.