diff options
author | kvik <kvik@a-b.xyz> | 2020-09-20 14:49:12 +0200 |
---|---|---|
committer | kvik <kvik@a-b.xyz> | 2020-09-20 14:49:12 +0200 |
commit | aa7c8cac1145d0cd6e9117deaa1f8c9f418bca17 (patch) | |
tree | 46e284013e4eaf89b0a436e5a28d34f067c32492 /sys/src/cmd/syscall | |
parent | e3166b4fe83d12a29c265fe9a8f333369b35c663 (diff) |
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.
Diffstat (limited to 'sys/src/cmd/syscall')
-rw-r--r-- | sys/src/cmd/syscall/mkfile | 25 | ||||
-rw-r--r-- | sys/src/cmd/syscall/syscall.c | 207 |
2 files changed, 96 insertions, 136 deletions
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 @@ </$objtype/mkfile -CFLAGS=-I/sys/src/libc/9syscall $CFLAGS TARG=syscall OFILES=syscall.$O\ @@ -18,12 +17,24 @@ UPDATE=\ SYSCALL=/sys/src/libc/9syscall/sys.h tab.h: $SYSCALL - sed '/#define._X[0-9_]/d; - /#define.NSYSCALL/d; - s/#define.([A-Z0-9_][A-Z0-9_]*).*/ "\1", (int(*)(...))\1,/' $SYSCALL | - tr A-Z a-z > 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 <u.h> #include <libc.h> -#include <sys.h> #include <fcall.h> 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(l<clk-180L*24*60*60 || clk+24L*60*60<l){ - memmove(buf, t+4, 7); /* month and day */ - memmove(buf+7, t+23, 5); /* year */ - }else - memmove(buf, t+4, 12); /* skip day of week */ - buf[12] = 0; - return buf; + return (uintptr)s; +} + +void +catch(void *, char *msg) +{ + fprint(2, "syscall: received note: %s\n", msg); + noted(NDFLT); } void main(int argc, char *argv[]) { - int i, j, c; - int oflag, xflag, sflag; - vlong r; + int i; + int oflag, sflag; + vlong r, nbuf; Dir d; char strs[1024]; - char ebuf[1024]; + char ebuf[ERRMAX]; - fmtinstall('M', dirmodefmt); + fmtinstall('D', dirfmt); oflag = 0; - xflag = 0; sflag = 0; ARGBEGIN{ case 'o': @@ -95,97 +84,57 @@ main(int argc, char *argv[]) case 's': sflag++; break; - case 'x': - xflag++; - break; default: - goto Usage; + usage(); }ARGEND - if(argc<1 || argc>1+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<argc; i++) + if(argc < 1 || argc > 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<r; j++){ - if(j%16 == 0) - print("%.4x\t", j); - c = buf[j]&0xFF; - if('!'<=c && c<='~') - print(" %c ", c); - else - print("%.2ux ", c); - if(j%16 == 15) - print("\n"); - } - print("\n"); - } - if(sflag && r > 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); } |