15 typedef struct Str Str;
29 cwrite(int fd, char *path, char *cmd, int len)
31 if (write(fd, cmd, len) < len) {
32 fprint(2, "cwrite: %s: failed %d bytes: %r\n", path, len);
41 int cfd, tfd, forking = 0, pid, newpid;
45 pid = (int)(uintptr)v;
46 ctl = smprint("/proc/%d/ctl", pid);
47 if ((cfd = open(ctl, OWRITE)) < 0)
48 die(smprint("%s: %r", ctl));
49 truss = smprint("/proc/%d/syscall", pid);
50 if ((tfd = open(truss, OREAD)) < 0)
51 die(smprint("%s: %r", truss));
53 cwrite(cfd, ctl, "stop", 4);
54 cwrite(cfd, truss, "startsyscall", 12);
56 s = mallocz(sizeof(Str) + Bufsize, 1);
57 s->buf = (char *)&s[1];
58 while((s->len = pread(tfd, s->buf, Bufsize - 1, 0)) > 0){
59 if (forking && s->buf[1] == '=' && s->buf[3] != '-') {
61 newpid = strtol(&s->buf[3], 0, 0);
62 sendp(forkc, (void*)newpid);
63 procrfork(reader, (void*)newpid, Stacksize, 0);
67 * There are three tests here and they (I hope) guarantee
70 if (strstr(s->buf, " Rfork") != nil) {
75 if (tokenize(rf, a, 8) == 5) {
78 flags = strtoul(a[4], 0, 16);
85 cwrite(cfd, truss, "startsyscall", 12);
86 s = mallocz(sizeof(Str) + Bufsize, 1);
87 s->buf = (char *)&s[1];
119 /* it's a nice null terminated thing */
120 fprint(2, "%s", s->buf);
124 // procrfork(reader, (void*)newpid, Stacksize, 0);
135 fprint(2, "Usage: ratrace [-c cmd [arg...]] | [pid]\n");
140 threadmain(int argc, char **argv)
147 * don't bother with fancy arg processing, because it picks up options
148 * for the command you are starting. Just check for -c as argv[1]
149 * and then take it from there.
153 if (argv[1][0] == '-')
158 cmd = strdup(argv[2]);
169 sysfatal("fork failed: %r");
173 exec(smprint("/bin/%s", cmd), args);
174 sysfatal("exec %s failed: %r", cmd);
182 out = chancreate(sizeof(char*), 0);
183 quit = chancreate(sizeof(char*), 0);
184 forkc = chancreate(sizeof(ulong *), 0);
186 procrfork(writer, nil, Stacksize, 0);