16 typedef struct Str Str;
30 cwrite(int fd, char *path, char *cmd, int len)
32 if (write(fd, cmd, len) < len) {
33 fprint(2, "cwrite: %s: failed %d bytes: %r\n", path, len);
42 int cfd, tfd, forking = 0, pid, newpid;
46 pid = (int)(uintptr)v;
47 ctl = smprint("/proc/%d/ctl", pid);
48 if ((cfd = open(ctl, OWRITE)) < 0)
49 die(smprint("%s: %r", ctl));
50 truss = smprint("/proc/%d/syscall", pid);
51 if ((tfd = open(truss, OREAD)) < 0)
52 die(smprint("%s: %r", truss));
54 cwrite(cfd, ctl, "stop", 4);
55 cwrite(cfd, truss, "startsyscall", 12);
57 s = mallocz(sizeof(Str) + Bufsize, 1);
58 s->buf = (char *)&s[1];
59 while((s->len = pread(tfd, s->buf, Bufsize - 1, 0)) > 0){
60 if (forking && s->buf[1] == '=' && s->buf[3] != '-') {
62 newpid = strtol(&s->buf[3], 0, 0);
63 sendp(forkc, (void*)newpid);
64 procrfork(reader, (void*)newpid, Stacksize, 0);
68 * There are three tests here and they (I hope) guarantee
71 if (strstr(s->buf, " Rfork") != nil) {
76 if (tokenize(rf, a, 8) == 5) {
79 flags = strtoul(a[4], 0, 16);
86 cwrite(cfd, truss, "startsyscall", 12);
87 s = mallocz(sizeof(Str) + Bufsize, 1);
88 s->buf = (char *)&s[1];
120 /* it's a nice null terminated thing */
121 fprint(2, "%s", s->buf);
125 // procrfork(reader, (void*)newpid, Stacksize, 0);
136 fprint(2, "Usage: ratrace [-c cmd [arg...]] | [pid]\n");
141 threadmain(int argc, char **argv)
148 * don't bother with fancy arg processing, because it picks up options
149 * for the command you are starting. Just check for -c as argv[1]
150 * and then take it from there.
154 if (argv[1][0] == '-')
159 cmd = strdup(argv[2]);
170 sysfatal("fork failed: %r");
174 exec(smprint("/bin/%s", cmd), args);
175 sysfatal("exec %s failed: %r", cmd);
183 out = chancreate(sizeof(char*), 0);
184 quit = chancreate(sizeof(char*), 0);
185 forkc = chancreate(sizeof(ulong *), 0);
187 procrfork(writer, nil, Stacksize, 0);