xref: /plan9/sys/src/cmd/syscall/syscall.c (revision 1c91605c2ba4c4f48e9e82b6f1ed88197f96bb37)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <sys.h>
49a747e4fSDavid du Colombier #include <fcall.h>
53e12c5d1SDavid du Colombier 
6425afbabSDavid du Colombier char	buf[1048576];
73e12c5d1SDavid du Colombier #define	NARG	5
874f16c81SDavid du Colombier uintptr	arg[NARG];
93e12c5d1SDavid du Colombier 
109a747e4fSDavid du Colombier /* system calls not defined in libc.h */
113e12c5d1SDavid du Colombier int	sysr1(void);
129a747e4fSDavid du Colombier int	_stat(char*, char*);
139a747e4fSDavid du Colombier int	_fstat(int, char*);
149a747e4fSDavid du Colombier int	_errstr(char*);
159a747e4fSDavid du Colombier int	_wstat(char*, char*);
169a747e4fSDavid du Colombier int	_fwstat(int, char*);
179a747e4fSDavid du Colombier int	_read(int, void*, int);
189a747e4fSDavid du Colombier int	_write(int, void*, int);
199a747e4fSDavid du Colombier int	_read9p(int, void*, int);
209a747e4fSDavid du Colombier int	_write9p(int, void*, int);
217b6fd1d2SDavid du Colombier int	brk_(void*);
229a747e4fSDavid du Colombier int	_nfstat(int, void*, int);
239a747e4fSDavid du Colombier int	_nstat(char*, void*, int);
249a747e4fSDavid du Colombier int	_nfwstat(int, void*, int);
259a747e4fSDavid du Colombier int	_nwstat(char*, void*, int);
269a747e4fSDavid du Colombier int	_fsession(char*, void*, int);
279a747e4fSDavid du Colombier int	_mount(int, char*, int, char*);
289a747e4fSDavid du Colombier int	_wait(void*);
293e12c5d1SDavid du Colombier 
303e12c5d1SDavid du Colombier struct{
313e12c5d1SDavid du Colombier 	char	*name;
323e12c5d1SDavid du Colombier 	int	(*func)(...);
333e12c5d1SDavid du Colombier }tab[]={
343e12c5d1SDavid du Colombier #include "tab.h"
353e12c5d1SDavid du Colombier 	0,		0
363e12c5d1SDavid du Colombier };
373e12c5d1SDavid du Colombier 
3874f16c81SDavid du Colombier uintptr parse(char *);
399a747e4fSDavid du Colombier void catch(void*, char*);
409a747e4fSDavid du Colombier 
419a747e4fSDavid du Colombier char*
xctime(ulong t)429a747e4fSDavid du Colombier xctime(ulong t)
439a747e4fSDavid du Colombier {
449a747e4fSDavid du Colombier 	char *buf, *s;
459a747e4fSDavid du Colombier 
469a747e4fSDavid du Colombier 	s = ctime(t);
479a747e4fSDavid du Colombier 	s[strlen(s)-1] = '\0';	/* remove newline */
489a747e4fSDavid du Colombier 	buf = malloc(512);
499a747e4fSDavid du Colombier 	if(buf == nil)
509a747e4fSDavid du Colombier 		sysfatal("can't malloc: %r");
519a747e4fSDavid du Colombier 	snprint(buf, 512, "%s (%lud)", s, t);
529a747e4fSDavid du Colombier 	return buf;
539a747e4fSDavid du Colombier }
549a747e4fSDavid du Colombier 
559a747e4fSDavid du Colombier 
569a747e4fSDavid du Colombier char*
lstime(long l)579a747e4fSDavid du Colombier lstime(long l)
589a747e4fSDavid du Colombier {
599a747e4fSDavid du Colombier 	static char buf[32];
609a747e4fSDavid du Colombier 	char *t;
619a747e4fSDavid du Colombier 	long clk;
629a747e4fSDavid du Colombier 
639a747e4fSDavid du Colombier 	clk = time(0);
649a747e4fSDavid du Colombier 	t = ctime(l);
659a747e4fSDavid du Colombier 	/* 6 months in the past or a day in the future */
669a747e4fSDavid du Colombier 	if(l<clk-180L*24*60*60 || clk+24L*60*60<l){
679a747e4fSDavid du Colombier 		memmove(buf, t+4, 7);		/* month and day */
689a747e4fSDavid du Colombier 		memmove(buf+7, t+23, 5);		/* year */
699a747e4fSDavid du Colombier 	}else
709a747e4fSDavid du Colombier 		memmove(buf, t+4, 12);		/* skip day of week */
719a747e4fSDavid du Colombier 	buf[12] = 0;
729a747e4fSDavid du Colombier 	return buf;
739a747e4fSDavid du Colombier }
749a747e4fSDavid du Colombier 
757dd7cddfSDavid du Colombier void
main(int argc,char * argv[])763e12c5d1SDavid du Colombier main(int argc, char *argv[])
773e12c5d1SDavid du Colombier {
789a747e4fSDavid du Colombier 	int i, j, c;
799a747e4fSDavid du Colombier 	int oflag, xflag, sflag;
809a747e4fSDavid du Colombier 	vlong r;
819a747e4fSDavid du Colombier 	Dir d;
829a747e4fSDavid du Colombier 	char strs[1024];
839a747e4fSDavid du Colombier 	char ebuf[1024];
843e12c5d1SDavid du Colombier 
859a747e4fSDavid du Colombier 	fmtinstall('M', dirmodefmt);
869a747e4fSDavid du Colombier 
879a747e4fSDavid du Colombier 	oflag = 0;
889a747e4fSDavid du Colombier 	xflag = 0;
899a747e4fSDavid du Colombier 	sflag = 0;
903e12c5d1SDavid du Colombier 	ARGBEGIN{
913e12c5d1SDavid du Colombier 	case 'o':
923e12c5d1SDavid du Colombier 		oflag++;
933e12c5d1SDavid du Colombier 		break;
949a747e4fSDavid du Colombier 	case 's':
959a747e4fSDavid du Colombier 		sflag++;
969a747e4fSDavid du Colombier 		break;
979a747e4fSDavid du Colombier 	case 'x':
989a747e4fSDavid du Colombier 		xflag++;
999a747e4fSDavid du Colombier 		break;
1003e12c5d1SDavid du Colombier 	default:
1013e12c5d1SDavid du Colombier 		goto Usage;
1023e12c5d1SDavid du Colombier 	}ARGEND
1033e12c5d1SDavid du Colombier 	if(argc<1 || argc>1+NARG){
1043e12c5d1SDavid du Colombier     Usage:
105*1c91605cSDavid du Colombier 		fprint(2, "usage: syscall [-ox] entry [args; buf==1MB buffer]\n");
1063e12c5d1SDavid du Colombier 		fprint(2, "\tsyscall write 1 hello 5\n");
1079a747e4fSDavid du Colombier 		fprint(2, "\tsyscall -o errstr buf 1024\n");
1089a747e4fSDavid du Colombier 		fprint(2, "\tsyscall -[xs] stat file buf 1024\n");
1097dd7cddfSDavid du Colombier 		exits("usage");
1103e12c5d1SDavid du Colombier 	}
1113e12c5d1SDavid du Colombier 	for(i=1; i<argc; i++)
1123e12c5d1SDavid du Colombier 		arg[i-1] = parse(argv[i]);
1139a747e4fSDavid du Colombier 	notify(catch);
1143e12c5d1SDavid du Colombier 	for(i=0; tab[i].name; i++)
1153e12c5d1SDavid du Colombier 		if(strcmp(tab[i].name, argv[0])==0){
1169a747e4fSDavid du Colombier 			/* special case for seek, pread, pwrite; vlongs are problematic */
11780ee5cbfSDavid du Colombier 			if(strcmp(argv[0], "seek") == 0)
1189a747e4fSDavid du Colombier 				r=seek(arg[0], strtoll(argv[2], 0, 0), arg[2]);
1199a747e4fSDavid du Colombier 			else if(strcmp(argv[0], "pread") == 0)
1209a747e4fSDavid du Colombier 				r=pread(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0));
1219a747e4fSDavid du Colombier 			else if(strcmp(argv[0], "pwrite") == 0)
1229a747e4fSDavid du Colombier 				r=pwrite(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0));
12380ee5cbfSDavid du Colombier 			else
1243e12c5d1SDavid du Colombier 				r=(*tab[i].func)(arg[0], arg[1], arg[2], arg[3], arg[4]);
1253e12c5d1SDavid du Colombier 			if(r == -1){
1269a747e4fSDavid du Colombier 				errstr(ebuf, sizeof ebuf);
1279a747e4fSDavid du Colombier 				fprint(2, "syscall: return %lld, error:%s\n", r, ebuf);
1283e12c5d1SDavid du Colombier 			}else{
1293e12c5d1SDavid du Colombier 				ebuf[0] = 0;
1309a747e4fSDavid du Colombier 				fprint(2, "syscall: return %lld, no error\n", r);
1313e12c5d1SDavid du Colombier 			}
1323e12c5d1SDavid du Colombier 			if(oflag)
1333e12c5d1SDavid du Colombier 				print("%s\n", buf);
1349a747e4fSDavid du Colombier 			if(xflag){
1359a747e4fSDavid du Colombier 				for(j=0; j<r; j++){
1369a747e4fSDavid du Colombier 					if(j%16 == 0)
1379a747e4fSDavid du Colombier 						print("%.4x\t", j);
1389a747e4fSDavid du Colombier 					c = buf[j]&0xFF;
1399a747e4fSDavid du Colombier 					if('!'<=c && c<='~')
1409a747e4fSDavid du Colombier 						print(" %c ", c);
1419a747e4fSDavid du Colombier 					else
1429a747e4fSDavid du Colombier 						print("%.2ux ", c);
1439a747e4fSDavid du Colombier 					if(j%16 == 15)
1449a747e4fSDavid du Colombier 						print("\n");
1459a747e4fSDavid du Colombier 				}
1469a747e4fSDavid du Colombier 				print("\n");
1479a747e4fSDavid du Colombier 			}
1489a747e4fSDavid du Colombier 			if(sflag && r > 0){
1499a747e4fSDavid du Colombier 				r = convM2D((uchar*)buf, r, &d, strs);
1509a747e4fSDavid du Colombier 				if(r <= BIT16SZ)
1519a747e4fSDavid du Colombier 					print("short stat message\n");
1529a747e4fSDavid du Colombier 				else{
1539a747e4fSDavid du Colombier 					print("[%s] ", d.muid);
1549a747e4fSDavid du Colombier 					print("(%.16llux %lud %.2ux) ", d.qid.path, d.qid.vers, d.qid.type);
155d9306527SDavid du Colombier 					print("%M (%luo) ", d.mode, d.mode);
1569a747e4fSDavid du Colombier 					print("%c %d ", d.type, d.dev);
1579a747e4fSDavid du Colombier 					print("%s %s ", d.uid, d.gid);
1589a747e4fSDavid du Colombier 					print("%lld ", d.length);
1599a747e4fSDavid du Colombier 					print("%s ", lstime(d.mtime));
1609a747e4fSDavid du Colombier 					print("%s\n", d.name);
161d9306527SDavid du Colombier 					print("\tmtime: %s\n\tatime: %s\n", xctime(d.mtime), xctime(d.atime));
1629a747e4fSDavid du Colombier 				}
1639a747e4fSDavid du Colombier 			}
1643e12c5d1SDavid du Colombier 			exits(ebuf);
1653e12c5d1SDavid du Colombier 		}
1663e12c5d1SDavid du Colombier 	fprint(2, "syscall: %s not known\n", argv[0]);
1673e12c5d1SDavid du Colombier 	exits("unknown");
1683e12c5d1SDavid du Colombier }
1699a747e4fSDavid du Colombier 
17074f16c81SDavid du Colombier uintptr
parse(char * s)1713e12c5d1SDavid du Colombier parse(char *s)
1723e12c5d1SDavid du Colombier {
1733e12c5d1SDavid du Colombier 	char *t;
17474f16c81SDavid du Colombier 	uintptr l;
1753e12c5d1SDavid du Colombier 
1763e12c5d1SDavid du Colombier 	if(strcmp(s, "buf") == 0)
17774f16c81SDavid du Colombier 		return (uintptr)buf;
17874f16c81SDavid du Colombier 
17974f16c81SDavid du Colombier 	l = strtoull(s, &t, 0);
1803e12c5d1SDavid du Colombier 	if(t>s && *t==0)
1813e12c5d1SDavid du Colombier 		return l;
18274f16c81SDavid du Colombier 	return (uintptr)s;
1839a747e4fSDavid du Colombier }
1849a747e4fSDavid du Colombier 
1859a747e4fSDavid du Colombier void
catch(void *,char * msg)1869a747e4fSDavid du Colombier catch(void *, char *msg)
1879a747e4fSDavid du Colombier {
1889a747e4fSDavid du Colombier 	fprint(2, "syscall: received note='%s'\n", msg);
1899a747e4fSDavid du Colombier 	noted(NDFLT);
1903e12c5d1SDavid du Colombier }
191