home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 4 / 4000 / process.c < prev   
Encoding:
C/C++ Source or Header  |  1991-09-09  |  11.6 KB  |  545 lines

  1. /*
  2.  * @(#)process.c    1.5 91/09/05
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <sys/types.h>
  7. #include <sys/ptrace.h>
  8. #include <sys/file.h>
  9. #include <sys/stat.h>
  10. #include <sys/time.h>
  11. #include <sys/wait.h>
  12. #include <sys/resource.h>
  13. #include <sys/utsname.h>
  14. #include <sys/ptrace.h>
  15. #include <sys/user.h>
  16. #include <machine/reg.h>
  17.  
  18. #include "defs.h"
  19.  
  20. int
  21. sys_gethostid(tcp)
  22. struct tcb *tcp;
  23. {
  24.     if (exiting(tcp)) {
  25.         fprintf(outf, "%x", tcp->u_args[0]);
  26.     }
  27.     return 0;
  28. }
  29.  
  30. int
  31. sys_sethostname(tcp)
  32. struct tcb *tcp;
  33. {
  34.     if (entering(tcp)) {
  35.         printstr(tcp->pid, tcp->u_args[0], -1);
  36.         fprintf(outf, ", %u", tcp->u_args[1]);
  37.     }
  38.     return 0;
  39. }
  40.  
  41. int
  42. sys_gethostname(tcp)
  43. struct tcb *tcp;
  44. {
  45.     if (exiting(tcp)) {
  46.         if (syserror(tcp))
  47.             fprintf(outf, "%#x", tcp->u_args[0]);
  48.         else
  49.             printstr(tcp->pid, tcp->u_args[0], -1);
  50.         fprintf(outf, ", %u", tcp->u_args[1]);
  51.     }
  52.     return 0;
  53. }
  54.  
  55. int
  56. sys_getpid(tcp)
  57. struct tcb *tcp;
  58. {
  59.     if (exiting(tcp)) {
  60.         fprintf(outf, "[ppid: %u]", getrval2(tcp->pid));
  61.     }
  62.     return 0;
  63. }
  64.  
  65. int
  66. sys_setdomainname(tcp)
  67. struct tcb *tcp;
  68. {
  69.     if (entering(tcp)) {
  70.         printstr(tcp->pid, tcp->u_args[0], -1);
  71.         fprintf(outf, ", %u", tcp->u_args[1]);
  72.     }
  73.     return 0;
  74. }
  75.  
  76. int
  77. sys_getdomainname(tcp)
  78. struct tcb *tcp;
  79. {
  80.     if (exiting(tcp)) {
  81.         if (syserror(tcp))
  82.             fprintf(outf, "%#x", tcp->u_args[0]);
  83.         else
  84.             printstr(tcp->pid, tcp->u_args[0], -1);
  85.         fprintf(outf, ", %u", tcp->u_args[1]);
  86.     }
  87.     return 0;
  88. }
  89.  
  90. int
  91. sys_rexit(tcp)
  92. struct tcb *tcp;
  93. {
  94.     if (exiting(tcp)) {
  95.         fprintf(stderr, "rexit returned!!\n");
  96.         return -1;
  97.     }
  98.     /* special case: we stop tracing this process, finish line now */
  99.     fprintf(outf, "%d) = ?\n", tcp->u_args[0]);
  100.     tcp->flags |= TCB_EXITING;
  101.     return 0;
  102. }
  103.  
  104. static int vforking;
  105.  
  106. int
  107. sys_fork(tcp)
  108. struct tcb *tcp;
  109. {
  110.     int pid;
  111.     struct tcb *tcpchild;
  112.  
  113.     if (entering(tcp)) {
  114.         if (!followfork || vforking)
  115.             return 0;
  116.         if (setbpt(tcp) < 0)
  117.             return 0;
  118.     } else {
  119.         int bpt = tcp->flags & TCB_BPTSET;
  120.  
  121.         if (!followfork)
  122.             return 0;
  123.         if (bpt)
  124.             clearbpt(tcp);
  125.  
  126.         if (syserror(tcp))
  127.             return 0;
  128.  
  129.         pid = tcp->u_rval;
  130.         if ((tcpchild = alloctcb(pid)) == NULLTCB) {
  131.             fprintf(stderr, " [tcb table full]\n");
  132.             /* XXX */kill(pid, SIGKILL);
  133.             return 0;
  134.         }
  135.         if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
  136.             perror("PTRACE_ATTACH");
  137.             fprintf(stderr, " - Too late?\n");
  138.             /* XXX */kill(pid, SIGKILL);
  139.             droptcb(tcpchild);
  140.             return 0;
  141.         }
  142.         tcpchild->flags |= TCB_ATTACHED;
  143.         /* Child has BPT too, must be removed on first occasion */
  144.         if (bpt) {
  145.             tcpchild->flags |= TCB_BPTSET;
  146.             tcpchild->baddr |= tcp->baddr;
  147.             bcopy(tcp->inst, tcpchild->inst, sizeof tcpchild->inst);
  148.         }
  149.         newoutf(tcpchild);
  150.         tcpchild->parent = tcp;
  151.         tcp->nchildren++;
  152.         fprintf(stderr, " - Process %u attached\n", pid);
  153.     }
  154.     return 0;
  155. }
  156.  
  157. int
  158. sys_vfork(tcp)
  159. struct tcb *tcp;
  160. {
  161.     /* XXX - cannot use the same trick for vfork */
  162.     int res;
  163.  
  164.     vforking = 1;
  165.     res = sys_fork(tcp);
  166.     vforking = 0;
  167.     return res;
  168. }
  169.  
  170. int
  171. sys_getuid(tcp)
  172. struct tcb *tcp;
  173. {
  174.     if (exiting(tcp)) {
  175.         fprintf(outf, "[euid %u]", getrval2(tcp->pid));
  176.     }
  177.     return 0;
  178. }
  179.  
  180. int
  181. sys_getgid(tcp)
  182. struct tcb *tcp;
  183. {
  184.     if (exiting(tcp)) {
  185.         fprintf(outf, "[egid %u]", getrval2(tcp->pid));
  186.     }
  187.     return 0;
  188. }
  189.  
  190. int
  191. sys_setreuid(tcp)
  192. struct tcb *tcp;
  193. {
  194.     if (entering(tcp)) {
  195.         fprintf(outf, "%u, %u", tcp->u_args[0], tcp->u_args[1]);
  196.     }
  197.     return 0;
  198. }
  199.  
  200. int
  201. sys_setregid(tcp)
  202. struct tcb *tcp;
  203. {
  204.     if (entering(tcp)) {
  205.         fprintf(outf, "%u, %u", tcp->u_args[0], tcp->u_args[1]);
  206.     }
  207.     return 0;
  208. }
  209.  
  210. int
  211. sys_setgroups(tcp)
  212. struct tcb *tcp;
  213. {
  214.     int i, len, *gidset;
  215.  
  216.     if (entering(tcp)) {
  217.         len = tcp->u_args[0];
  218.         fprintf(outf, "%u, [", len);
  219.         if ((gidset = (int *)malloc(len * sizeof(int))) == NULL) {
  220.             fprintf(stderr, " [Out of memory]\n");
  221.             return -1;
  222.         }
  223.         umove(tcp->pid, tcp->u_args[1], len * sizeof(int), (char *)gidset);
  224.         for (i = 0; i < len; i++)
  225.             fprintf(outf, " %u", gidset[i]);
  226.         fprintf(outf, "]", gidset[i]);
  227.         free((char *)gidset);
  228.     }
  229.     return 0;
  230. }
  231.  
  232. int
  233. sys_getgroups(tcp)
  234. struct tcb *tcp;
  235. {
  236.     int i, len, *gidset;
  237.  
  238.     if (entering(tcp)) {
  239.         len = tcp->u_args[0];
  240.         fprintf(outf, "%u, [", len);
  241.     } else {
  242.         len = tcp->u_rval;
  243.         if ((gidset = (int *)malloc(len * sizeof(int))) == NULL) {
  244.             fprintf(stderr, " [Out of memory]\n");
  245.             return -1;
  246.         }
  247.         umove(tcp->pid, tcp->u_args[1], len * sizeof(int), (char *)gidset);
  248.         for (i = 0; i < len; i++)
  249.             fprintf(outf, " %u", gidset[i]);
  250.         fprintf(outf, "]", gidset[i]);
  251.         free((char *)gidset);
  252.     }
  253.     return 0;
  254. }
  255.  
  256. int
  257. sys_setpgrp(tcp)
  258. struct tcb *tcp;
  259. {
  260.     if (entering(tcp)) {
  261.         fprintf(outf, "%u, %u", tcp->u_args[0], tcp->u_args[1]);
  262.     }
  263.     return 0;
  264. }
  265.  
  266. int
  267. sys_getpgrp(tcp)
  268. struct tcb *tcp;
  269. {
  270.     if (entering(tcp)) {
  271.         fprintf(outf, "%u", tcp->u_args[0]);
  272.     }
  273.     return 0;
  274. }
  275.  
  276. int
  277. sys_setpgid(tcp)
  278. struct tcb *tcp;
  279. {
  280.     if (entering(tcp)) {
  281.         fprintf(outf, "%u, %u", tcp->u_args[0], tcp->u_args[1]);
  282.     }
  283.     return 0;
  284. }
  285.  
  286. static
  287. printargv(pid, addr)
  288. {
  289.     int cp;
  290.  
  291.     while(1) {
  292.         if (umove(pid, addr, sizeof(char *), (char *)&cp) < 0)
  293.             return -1;
  294.         if (cp == 0)
  295.             break;
  296.         if (printstr(pid, cp, -1) < 0)
  297.             return -1;
  298.         addr += sizeof(char *);
  299.     }
  300. }
  301.  
  302. int
  303. sys_execv(tcp)
  304. struct tcb *tcp;
  305. {
  306.     if (entering(tcp)) {
  307.         printstr(tcp->pid, tcp->u_args[0], -1);
  308.         fprintf(outf, ", ");
  309.         printargv(tcp->pid, tcp->u_args[1]);
  310.     }
  311.     return 0;
  312. }
  313.  
  314. int
  315. sys_execve(tcp)
  316. struct tcb *tcp;
  317. {
  318.     int cp, addr;
  319.  
  320.     if (entering(tcp)) {
  321.         printstr(tcp->pid, tcp->u_args[0], -1);
  322.         fprintf(outf, ", ");
  323.         printargv(tcp->pid, tcp->u_args[1]);
  324.         fprintf(outf, ", env: [");
  325.         printargv(tcp->pid, tcp->u_args[2]);
  326.         fprintf(outf, "]");
  327.     }
  328.     return 0;
  329. }
  330.  
  331. static Xlat wait4_options[] = {
  332.     WNOHANG,    "NOHANG",
  333.     WUNTRACED,    "UNTRACED",
  334.     0,        NULL,
  335. };
  336.  
  337. int
  338. sys_wait4(tcp)
  339. struct tcb *tcp;
  340. {
  341.     int options, status;
  342.     struct rusage rusage;
  343.  
  344.     if (entering(tcp)) {
  345.         fprintf(outf, "%d, ", tcp->u_args[0]);
  346.         if (tcp->nchildren > 0) /* There are traced children */ {
  347.             tcp->flags |= TCB_SUSPENDED;
  348.             tcp->waitpid = tcp->u_args[0];
  349.         }
  350.     } else {
  351.         if (tcp->u_rval == 0 || tcp->u_error) {
  352.             fprintf(outf, "%x, %x, %x", tcp->u_args[1],
  353.                     tcp->u_args[2], tcp->u_args[3]);
  354.             return 0;
  355.         }
  356.         /* status */
  357.         if (tcp->u_args[1]) {
  358.             umove(tcp->pid, tcp->u_args[1], sizeof status,
  359.                             (char *)&status);
  360.             if (WIFSTOPPED(status))
  361.                 fprintf(outf, "STOPPED(%s), ",
  362.                     signals[WSTOPSIG(status)]+3);
  363.             else if WIFSIGNALED(status)
  364.                 fprintf(outf, "SIGNALED(%s), ",
  365.                     signals[WTERMSIG(status)]+3);
  366.             else if WIFEXITED(status)
  367.                 fprintf(outf, "EXITED(%d), ",
  368.                     WEXITSTATUS(status));
  369.         } else
  370.             fprintf(outf, "(struct int *)0, ");
  371.         /* options */
  372.         if (!printflags(wait4_options, tcp->u_args[2]))
  373.             putc('0', outf);
  374.         /* usage */
  375.         if (tcp->u_args[3]) {
  376.             umove(tcp->pid, tcp->u_args[3], sizeof rusage,
  377.                             (char *)&rusage);
  378.             fprintf(outf, ", {stime %u,%u utime %u,%u ...}",
  379.                 rusage.ru_stime.tv_sec, rusage.ru_stime.tv_usec,
  380.                 rusage.ru_utime.tv_sec, rusage.ru_utime.tv_usec);
  381.         } else
  382.             fprintf(outf, ", (struct rusage *)0");
  383.     }
  384.     return 0;
  385. }
  386.  
  387. int
  388. sys_uname(tcp)
  389. struct tcb *tcp;
  390. {
  391.     struct utsname uname;
  392.  
  393.     if (exiting(tcp)) {
  394.         umove(tcp->pid, tcp->u_args[0], sizeof uname, (char *)&uname);
  395.         fprintf(outf, "{%s, %s, %s, %s, %s, %s}",
  396.             uname.sysname, uname.nodename,
  397.             uname.nodeext, uname.release,
  398.             uname.version, uname.machine);
  399.     }
  400.     return 0;
  401. }
  402.  
  403. static Xlat ptrace_cmds[] = {
  404.     PTRACE_TRACEME,    "TRACEME",    /* 0, by tracee to begin tracing */
  405.     PTRACE_PEEKTEXT,"PEEKTEXT",    /* 1, read word from text segment */
  406.     PTRACE_PEEKDATA,"PEEKDATA",    /* 2, read word from data segment */
  407.     PTRACE_PEEKUSER,"PEEKUSER",    /* 3, read word from user struct */
  408.     PTRACE_POKETEXT,"POKETEXT",    /* 4, write word into text segment */
  409.     PTRACE_POKEDATA,"POKEDATA",    /* 5, write word into data segment */
  410.     PTRACE_POKEUSER,"POKEUSER",    /* 6, write word into user struct */
  411.     PTRACE_CONT,    "CONT",            /* 7, continue process */
  412.     PTRACE_KILL,    "KILL",            /* 8, terminate process */
  413.     PTRACE_SINGLESTEP,    "SINGLESTEP",    /* 9, single step process */
  414.     PTRACE_ATTACH,    "ATTACH",        /* 10, attach to an existing process */
  415.     PTRACE_DETACH,    "DETACH",        /* 11, detach from a process */
  416.     PTRACE_GETREGS,    "GETREGS",        /* 12, get all registers */
  417.     PTRACE_SETREGS,    "SETREGS",        /* 13, set all registers */
  418.     PTRACE_GETFPREGS,"GETFPREGS",    /* 14, get all floating point regs */
  419.     PTRACE_SETFPREGS,"SETFPREGS",    /* 15, set all floating point regs */
  420.     PTRACE_READDATA,    "READDATA",    /* 16, read data segment */
  421.     PTRACE_WRITEDATA,    "WRITEDATA",    /* 17, write data segment */
  422.     PTRACE_READTEXT,    "READTEXT",    /* 18, read text segment */
  423.     PTRACE_WRITETEXT,    "WRITETEXT",    /* 19, write text segment */
  424.     PTRACE_GETFPAREGS,    "GETFPAREGS",    /* 20, get all fpa regs */
  425.     PTRACE_SETFPAREGS,    "SETFPAREGS",    /* 21, set all fpa regs */
  426. #ifdef    sparc
  427.     /*    currently unimplemented */
  428.     PTRACE_GETWINDOW,    "GETWINDOW",    /* 22, get register window n */
  429.     PTRACE_SETWINDOW,    "SETWINDOW",    /* 23, set register window n */
  430. #else    !sparc
  431.     PTRACE_22,    "PTRACE_22",            /* 22, filler */
  432.     PTRACE_23,    "PTRACE_23",            /* 23, filler */
  433. #endif    !sparc
  434.     PTRACE_SYSCALL,    "SYSCALL",    /* 24, trap next sys call */
  435.     PTRACE_DUMPCORE,    "DUMPCORE",    /* 25, dump process core */
  436. #ifdef    i386
  437.     PTRACE_SETWRBKPT,    "SETWRBKPT",    /* 26, set write breakpoint */
  438.     PTRACE_SETACBKPT,    "SETACBKPT",    /* 27, set access breakpoint */
  439.     PTRACE_CLRDR7,    "CLRDR7",        /* 28, clear debug register 7 */
  440. #else
  441.     PTRACE_26,    "PTRACE_26",            /* 26, filler */
  442.     PTRACE_27,    "PTRACE_27",            /* 27, filler */
  443.     PTRACE_28,    "PTRACE_28",            /* 28, filler */
  444. #endif
  445.     PTRACE_GETUCODE,    "PTRACE_GETUCODE",    /* 29, get u.u_code */
  446.     0,        NULL,
  447. };
  448.  
  449.  
  450. static Xlat u[] = {
  451.     uoff(u_pcb),    "u_pcb",
  452.     uoff(u_procp),    "u_procp",
  453.     uoff(u_ar0),    "u_ar0",
  454.     uoff(u_comm[0]),    "u_comm",
  455.     uoff(u_arg[0]),    "u_arg",
  456.     uoff(u_ap),    "u_ap",
  457.     uoff(u_qsave),    "u_qsave",
  458.     uoff(u_rval1),    "u_rval1",
  459.     uoff(u_rval2),    "u_rval2",
  460.     uoff(u_error),    "u_error",
  461.     uoff(u_eosys),    "u_eosys",
  462.     uoff(u_ssave),    "u_ssave",
  463.     uoff(u_signal[0]),    "u_signal",
  464.     uoff(u_sigmask[0]),    "u_sigmask",
  465.     uoff(u_sigonstack),    "u_sigonstack",
  466.     uoff(u_sigintr),    "u_sigintr",
  467.     uoff(u_sigreset),    "u_sigreset",
  468.     uoff(u_oldmask),    "u_oldmask",
  469.     uoff(u_code),    "u_code",
  470.     uoff(u_addr),    "u_addr",
  471.     uoff(u_sigstack),    "u_sigstack",
  472.     uoff(u_ofile),    "u_ofile",
  473.     uoff(u_pofile),    "u_pofile",
  474.     uoff(u_ofile_arr[0]),    "u_ofile_arr",
  475.     uoff(u_pofile_arr[0]),    "u_pofile_arr",
  476.     uoff(u_lastfile),    "u_lastfile",
  477.     uoff(u_cwd),    "u_cwd",
  478.     uoff(u_cdir),    "u_cdir",
  479.     uoff(u_rdir),    "u_rdir",
  480.     uoff(u_cmask),    "u_cmask",
  481.     uoff(u_ru),    "u_ru",
  482.     uoff(u_cru),    "u_cru",
  483.     uoff(u_timer[0]),    "u_timer",
  484.     uoff(u_XXX[0]),    "u_XXX",
  485.     uoff(u_ioch),    "u_ioch",
  486.     uoff(u_start),    "u_start",
  487.     uoff(u_acflag),    "u_acflag",
  488.     uoff(u_prof.pr_base),    "u_prof.pr_base",
  489.     uoff(u_prof.pr_size),    "u_prof.pr_size",
  490.     uoff(u_prof.pr_off),    "u_prof.pr_off",
  491.     uoff(u_prof.pr_scale),    "u_prof.pr_scale",
  492.     uoff(u_rlimit[0]),    "u_rlimit",
  493.     uoff(u_exdata.Ux_A),    "u_exdata.Ux_A",
  494.     uoff(u_exdata.ux_shell[0]),    "u_exdata.ux_shell",
  495.     uoff(u_lofault),    "u_lofault",
  496.     0,            NULL,
  497. };
  498.  
  499. int
  500. sys_ptrace(tcp)
  501. struct tcb *tcp;
  502. {
  503.     char *cmd;
  504.     Xlat *x;
  505.     int addr;
  506.  
  507.     cmd = xlookup(ptrace_cmds, tcp->u_args[0]);
  508.     if (!cmd) cmd = "PTRACE_???";
  509.     if (entering(tcp)) {
  510.         fprintf(outf, "%s, %u, ", cmd, tcp->u_args[1]);
  511.         addr = tcp->u_args[2];
  512.         if (tcp->u_args[0] == PTRACE_PEEKUSER) {
  513.             for (x = u; x->str; x++) {
  514.                 if (x->val >= addr)
  515.                     break;
  516.             }
  517.             if (x->val > addr && x != u) {
  518.                 x--;
  519.                 fprintf(outf, "%s[%x], ",
  520.                     x->str, addr - x->val);
  521.             } else {
  522.                 fprintf(outf, "%s, ", x->str);
  523.             }
  524.         } else {
  525.             fprintf(outf, "%#x, ", tcp->u_args[2]);
  526.         }
  527.         if (tcp->u_args[0] == PTRACE_WRITEDATA ||
  528.             tcp->u_args[0] == PTRACE_WRITETEXT) {
  529.             fprintf(outf, "%u, ", tcp->u_args[3]);
  530.             printstr(tcp->pid, tcp->u_args[4], tcp->u_args[3]);
  531.         } else if (tcp->u_args[0] != PTRACE_READDATA &&
  532.                 tcp->u_args[0] != PTRACE_READTEXT) {
  533.             fprintf(outf, "%#x", tcp->u_args[3]);
  534.         }
  535.     } else {
  536.         if (tcp->u_args[0] == PTRACE_READDATA ||
  537.             tcp->u_args[0] == PTRACE_READTEXT) {
  538.             fprintf(outf, "%u, ", tcp->u_args[3]);
  539.             printstr(tcp->pid, tcp->u_args[4], tcp->u_args[3]);
  540.         }
  541.     }
  542.     return 0;
  543. }
  544.  
  545.