From aa7c8cac1145d0cd6e9117deaa1f8c9f418bca17 Mon Sep 17 00:00:00 2001 From: kvik Date: Sun, 20 Sep 2020 14:49:12 +0200 Subject: syscall: utility overhaul Following is a list of functional changes: * The -o flag outputs the entire buffer to the length returned by the syscall, or, in case of fd2path(2) and errstr(2), to '\0'. * The -x flag is removed; the above makes it possible to pipe into xd(1) to get the same result. * The -s flag uses dirfmt(2) to format the stat message, instead of trying to imitate ls(1). * Stderr reports are normalized and made easier to parse. The code also suffered a number of stylistic changes. --- sys/src/cmd/syscall/mkfile | 25 +++-- sys/src/cmd/syscall/syscall.c | 207 ++++++++++++++++-------------------------- 2 files changed, 96 insertions(+), 136 deletions(-) (limited to 'sys/src/cmd/syscall') diff --git a/sys/src/cmd/syscall/mkfile b/sys/src/cmd/syscall/mkfile index 9da809b24..18985a0ec 100644 --- a/sys/src/cmd/syscall/mkfile +++ b/sys/src/cmd/syscall/mkfile @@ -1,5 +1,4 @@ tab.h - echo ' "read", (int(*)(...))read,' >> tab.h - echo ' "write", (int(*)(...))write,' >> tab.h + awk ' + BEGIN{ print "enum{" } + { printf "%s, ", $2 } + END{ + print "READ, WRITE, NTAB" + print "};" + }' <$SYSCALL >$target + awk ' + BEGIN{ print "struct Call tab[] = {" } + { printf "[%s] \"%s\", (int(*)(...))%s,\n", + $2, tolower($2), tolower($2) + } + END{ + print "[READ] \"read\", (int(*)(...))read," + print "[WRITE] \"write\", (int(*)(...))write," + print "[NTAB] nil, 0" + print "};" + }' <$SYSCALL >>$target clean:V: rm -f *.[$OS] [$OS].out $TARG $HFILES diff --git a/sys/src/cmd/syscall/syscall.c b/sys/src/cmd/syscall/syscall.c index 7d417e5e8..09c125c0c 100644 --- a/sys/src/cmd/syscall/syscall.c +++ b/sys/src/cmd/syscall/syscall.c @@ -1,10 +1,9 @@ #include #include -#include #include char buf[1048576]; -#define NARG 5 +enum{ NARG = 5 }; uintptr arg[NARG]; /* system calls not defined in libc.h */ @@ -28,65 +27,55 @@ int _mount(int, char*, int, char*); int _wait(void*); int _nsec(vlong*); -struct{ +struct Call{ char *name; int (*func)(...); -}tab[]={ -#include "tab.h" - 0, 0 }; +#include "tab.h" -uintptr parse(char *); -void catch(void*, char*); - -char* -xctime(ulong t) +void +usage(void) { - char *buf, *s; - - s = ctime(t); - s[strlen(s)-1] = '\0'; /* remove newline */ - buf = malloc(512); - if(buf == nil) - sysfatal("can't malloc: %r"); - snprint(buf, 512, "%s (%lud)", s, t); - return buf; + fprint(2, "usage: %s [-os] entry [arg ...]\n", argv0); + exits("usage"); } - -char* -lstime(long l) +uintptr +parse(char *s) { - static char buf[32]; char *t; - long clk; + uintptr l; + + if(strncmp(s, "buf", 3) == 0) + return (uintptr)buf; + + l = strtoull(s, &t, 0); + if(t > s && *t == 0) + return l; - clk = time(0); - t = ctime(l); - /* 6 months in the past or a day in the future */ - if(l1+NARG){ - Usage: - fprint(2, "usage: syscall [-ox] entry [args; buf==1MB buffer]\n"); - fprint(2, "\tsyscall write 1 hello 5\n"); - fprint(2, "\tsyscall -o errstr buf 1024\n"); - fprint(2, "\tsyscall -[xs] stat file buf 1024\n"); - exits("usage"); - } - for(i=1; i 1+NARG) + usage(); + + for(i = 1; i < argc; i++) arg[i-1] = parse(argv[i]); + for(i = 0; tab[i].name; i++) + if(strcmp(tab[i].name, argv[0]) == 0) + break; + if(i == NTAB){ + fprint(2, "syscall: %s not known\n", argv[0]); + exits("unknown"); + } notify(catch); - for(i=0; tab[i].name; i++) - if(strcmp(tab[i].name, argv[0])==0){ - /* special case for seek, pread, pwrite; vlongs are problematic */ - if(strcmp(argv[0], "seek") == 0) - r=seek(arg[0], strtoll(argv[2], 0, 0), arg[2]); - else if(strcmp(argv[0], "pread") == 0) - r=pread(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0)); - else if(strcmp(argv[0], "pwrite") == 0) - r=pwrite(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0)); - else - r=(*tab[i].func)(arg[0], arg[1], arg[2], arg[3], arg[4]); - if(r == -1){ - errstr(ebuf, sizeof ebuf); - fprint(2, "syscall: return %lld, error:%s\n", r, ebuf); - }else{ - ebuf[0] = 0; - fprint(2, "syscall: return %lld, no error\n", r); - } - if(oflag) - print("%s", buf); - if(xflag){ - for(j=0; j 0){ - r = convM2D((uchar*)buf, r, &d, strs); - if(r <= BIT16SZ) - print("short stat message\n"); - else{ - print("[%s] ", d.muid); - print("(%.16llux %lud %.2ux) ", d.qid.path, d.qid.vers, d.qid.type); - print("%M (%luo) ", d.mode, d.mode); - print("%c %d ", d.type, d.dev); - print("%s %s ", d.uid, d.gid); - print("%lld ", d.length); - print("%s ", lstime(d.mtime)); - print("%s\n", d.name); - print("\tmtime: %s\n\tatime: %s\n", xctime(d.mtime), xctime(d.atime)); - } - } - exits(ebuf); + /* special case for seek, pread, pwrite; vlongs are problematic */ + switch(i){ + default: + r = (*tab[i].func)(arg[0], arg[1], arg[2], arg[3], arg[4]); + break; + case SEEK: + r = seek(arg[0], strtoll(argv[2], 0, 0), arg[2]); + break; + case PREAD: + r = pread(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0)); + break; + case PWRITE: + r = pwrite(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0)); + break; + } + if(r == -1){ + errstr(ebuf, sizeof ebuf); + fprint(2, "syscall: return: %lld error: %s\n", r, ebuf); + exits(ebuf); + } + fprint(2, "syscall: return: %lld\n", r); + if(oflag){ + nbuf = r; + switch(i){ + case _ERRSTR: case ERRSTR: case FD2PATH: + nbuf = strlen(buf); } - fprint(2, "syscall: %s not known\n", argv[0]); - exits("unknown"); -} - -uintptr -parse(char *s) -{ - char *t; - uintptr l; - - if(strcmp(s, "buf") == 0) - return (uintptr)buf; - - l = strtoull(s, &t, 0); - if(t>s && *t==0) - return l; - return (uintptr)s; -} - -void -catch(void *, char *msg) -{ - fprint(2, "syscall: received note='%s'\n", msg); - noted(NDFLT); + if(write(1, buf, nbuf) != nbuf) + sysfatal("write: %r"); + }else if(sflag){ + r = convM2D((uchar*)buf, r, &d, strs); + if(r <= BIT16SZ) + print("short stat message\n"); + else + print("%D\n", &d); + } + exits(nil); } -- cgit v1.2.3