xref: /plan9/sys/src/cmd/syscall/syscall.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
3*9a747e4fSDavid du Colombier #include <sys.h>
4*9a747e4fSDavid du Colombier #include <fcall.h>
53e12c5d1SDavid du Colombier 
63e12c5d1SDavid du Colombier char	buf[8192];
73e12c5d1SDavid du Colombier #define	NARG	5
8*9a747e4fSDavid du Colombier long	arg[NARG];
93e12c5d1SDavid du Colombier 
10*9a747e4fSDavid du Colombier /* system calls not defined in libc.h */
113e12c5d1SDavid du Colombier int	sysr1(void);
12*9a747e4fSDavid du Colombier int	_stat(char*, char*);
13*9a747e4fSDavid du Colombier int	_fstat(int, char*);
14*9a747e4fSDavid du Colombier int	_errstr(char*);
15*9a747e4fSDavid du Colombier int	_wstat(char*, char*);
16*9a747e4fSDavid du Colombier int	_fwstat(int, char*);
17*9a747e4fSDavid du Colombier int	_read(int, void*, int);
18*9a747e4fSDavid du Colombier int	_write(int, void*, int);
19*9a747e4fSDavid du Colombier int	_read9p(int, void*, int);
20*9a747e4fSDavid du Colombier int	_write9p(int, void*, int);
21*9a747e4fSDavid du Colombier int	brk_(int);
22*9a747e4fSDavid du Colombier int	_nfstat(int, void*, int);
23*9a747e4fSDavid du Colombier int	_nstat(char*, void*, int);
24*9a747e4fSDavid du Colombier int	_nfwstat(int, void*, int);
25*9a747e4fSDavid du Colombier int	_nwstat(char*, void*, int);
26*9a747e4fSDavid du Colombier int	_fsession(char*, void*, int);
27*9a747e4fSDavid du Colombier int	_mount(int, char*, int, char*);
28*9a747e4fSDavid 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 
38*9a747e4fSDavid du Colombier long parse(char *);
39*9a747e4fSDavid du Colombier void catch(void*, char*);
40*9a747e4fSDavid du Colombier 
41*9a747e4fSDavid du Colombier char*
42*9a747e4fSDavid du Colombier xctime(ulong t)
43*9a747e4fSDavid du Colombier {
44*9a747e4fSDavid du Colombier 	char *buf, *s;
45*9a747e4fSDavid du Colombier 
46*9a747e4fSDavid du Colombier 	s = ctime(t);
47*9a747e4fSDavid du Colombier 	s[strlen(s)-1] = '\0';	/* remove newline */
48*9a747e4fSDavid du Colombier 	buf = malloc(512);
49*9a747e4fSDavid du Colombier 	if(buf == nil)
50*9a747e4fSDavid du Colombier 		sysfatal("can't malloc: %r");
51*9a747e4fSDavid du Colombier 	snprint(buf, 512, "%s (%lud)", s, t);
52*9a747e4fSDavid du Colombier 	return buf;
53*9a747e4fSDavid du Colombier }
54*9a747e4fSDavid du Colombier 
55*9a747e4fSDavid du Colombier 
56*9a747e4fSDavid du Colombier char*
57*9a747e4fSDavid du Colombier lstime(long l)
58*9a747e4fSDavid du Colombier {
59*9a747e4fSDavid du Colombier 	static char buf[32];
60*9a747e4fSDavid du Colombier 	char *t;
61*9a747e4fSDavid du Colombier 	long clk;
62*9a747e4fSDavid du Colombier 
63*9a747e4fSDavid du Colombier 	clk = time(0);
64*9a747e4fSDavid du Colombier 	t = ctime(l);
65*9a747e4fSDavid du Colombier 	/* 6 months in the past or a day in the future */
66*9a747e4fSDavid du Colombier 	if(l<clk-180L*24*60*60 || clk+24L*60*60<l){
67*9a747e4fSDavid du Colombier 		memmove(buf, t+4, 7);		/* month and day */
68*9a747e4fSDavid du Colombier 		memmove(buf+7, t+23, 5);		/* year */
69*9a747e4fSDavid du Colombier 	}else
70*9a747e4fSDavid du Colombier 		memmove(buf, t+4, 12);		/* skip day of week */
71*9a747e4fSDavid du Colombier 	buf[12] = 0;
72*9a747e4fSDavid du Colombier 	return buf;
73*9a747e4fSDavid du Colombier }
74*9a747e4fSDavid du Colombier 
757dd7cddfSDavid du Colombier void
763e12c5d1SDavid du Colombier main(int argc, char *argv[])
773e12c5d1SDavid du Colombier {
78*9a747e4fSDavid du Colombier 	int i, j, c;
79*9a747e4fSDavid du Colombier 	int oflag, xflag, sflag;
80*9a747e4fSDavid du Colombier 	vlong r;
81*9a747e4fSDavid du Colombier 	Dir d;
82*9a747e4fSDavid du Colombier 	char strs[1024];
83*9a747e4fSDavid du Colombier 	char ebuf[1024];
843e12c5d1SDavid du Colombier 
85*9a747e4fSDavid du Colombier 	fmtinstall('M', dirmodefmt);
86*9a747e4fSDavid du Colombier 
87*9a747e4fSDavid du Colombier 	oflag = 0;
88*9a747e4fSDavid du Colombier 	xflag = 0;
89*9a747e4fSDavid du Colombier 	sflag = 0;
903e12c5d1SDavid du Colombier 	ARGBEGIN{
913e12c5d1SDavid du Colombier 	case 'o':
923e12c5d1SDavid du Colombier 		oflag++;
933e12c5d1SDavid du Colombier 		break;
94*9a747e4fSDavid du Colombier 	case 's':
95*9a747e4fSDavid du Colombier 		sflag++;
96*9a747e4fSDavid du Colombier 		break;
97*9a747e4fSDavid du Colombier 	case 'x':
98*9a747e4fSDavid du Colombier 		xflag++;
99*9a747e4fSDavid 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*9a747e4fSDavid du Colombier 		fprint(2, "usage: syscall [-ox] entry [args; buf==8192 byte buffer]\n");
1063e12c5d1SDavid du Colombier 		fprint(2, "\tsyscall write 1 hello 5\n");
107*9a747e4fSDavid du Colombier 		fprint(2, "\tsyscall -o errstr buf 1024\n");
108*9a747e4fSDavid 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]);
113*9a747e4fSDavid 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){
116*9a747e4fSDavid du Colombier 			/* special case for seek, pread, pwrite; vlongs are problematic */
11780ee5cbfSDavid du Colombier 			if(strcmp(argv[0], "seek") == 0)
118*9a747e4fSDavid du Colombier 				r=seek(arg[0], strtoll(argv[2], 0, 0), arg[2]);
119*9a747e4fSDavid du Colombier 			else if(strcmp(argv[0], "pread") == 0)
120*9a747e4fSDavid du Colombier 				r=pread(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0));
121*9a747e4fSDavid du Colombier 			else if(strcmp(argv[0], "pwrite") == 0)
122*9a747e4fSDavid 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){
126*9a747e4fSDavid du Colombier 				errstr(ebuf, sizeof ebuf);
127*9a747e4fSDavid du Colombier 				fprint(2, "syscall: return %lld, error:%s\n", r, ebuf);
1283e12c5d1SDavid du Colombier 			}else{
1293e12c5d1SDavid du Colombier 				ebuf[0] = 0;
130*9a747e4fSDavid 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);
134*9a747e4fSDavid du Colombier 			if(xflag){
135*9a747e4fSDavid du Colombier 				for(j=0; j<r; j++){
136*9a747e4fSDavid du Colombier 					if(j%16 == 0)
137*9a747e4fSDavid du Colombier 						print("%.4x\t", j);
138*9a747e4fSDavid du Colombier 					c = buf[j]&0xFF;
139*9a747e4fSDavid du Colombier 					if('!'<=c && c<='~')
140*9a747e4fSDavid du Colombier 						print(" %c ", c);
141*9a747e4fSDavid du Colombier 					else
142*9a747e4fSDavid du Colombier 						print("%.2ux ", c);
143*9a747e4fSDavid du Colombier 					if(j%16 == 15)
144*9a747e4fSDavid du Colombier 						print("\n");
145*9a747e4fSDavid du Colombier 				}
146*9a747e4fSDavid du Colombier 				print("\n");
147*9a747e4fSDavid du Colombier 			}
148*9a747e4fSDavid du Colombier 			if(sflag && r > 0){
149*9a747e4fSDavid du Colombier 				r = convM2D((uchar*)buf, r, &d, strs);
150*9a747e4fSDavid du Colombier 				if(r <= BIT16SZ)
151*9a747e4fSDavid du Colombier 					print("short stat message\n");
152*9a747e4fSDavid du Colombier 				else{
153*9a747e4fSDavid du Colombier 					print("[%s] ", d.muid);
154*9a747e4fSDavid du Colombier 					print("(%.16llux %lud %.2ux) ", d.qid.path, d.qid.vers, d.qid.type);
155*9a747e4fSDavid du Colombier 					print("%M ", d.mode);
156*9a747e4fSDavid du Colombier 					print("%c %d ", d.type, d.dev);
157*9a747e4fSDavid du Colombier 					print("%s %s ", d.uid, d.gid);
158*9a747e4fSDavid du Colombier 					print("%lld ", d.length);
159*9a747e4fSDavid du Colombier 					print("%s ", lstime(d.mtime));
160*9a747e4fSDavid du Colombier 					print("%s\n", d.name);
161*9a747e4fSDavid du Colombier 					print("\tmtime: %s; atime: %s\n", xctime(d.mtime), xctime(d.atime));
162*9a747e4fSDavid du Colombier 				}
163*9a747e4fSDavid 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 }
169*9a747e4fSDavid du Colombier 
170*9a747e4fSDavid du Colombier long
1713e12c5d1SDavid du Colombier parse(char *s)
1723e12c5d1SDavid du Colombier {
1733e12c5d1SDavid du Colombier 	char *t;
1743e12c5d1SDavid du Colombier 	long l;
1753e12c5d1SDavid du Colombier 
1763e12c5d1SDavid du Colombier 	if(strcmp(s, "buf") == 0)
1773e12c5d1SDavid du Colombier 		return (int)buf;
1783e12c5d1SDavid du Colombier 	l = strtoul(s, &t, 0);
1793e12c5d1SDavid du Colombier 	if(t>s && *t==0)
1803e12c5d1SDavid du Colombier 		return l;
181*9a747e4fSDavid du Colombier 	return (long)s;
182*9a747e4fSDavid du Colombier }
183*9a747e4fSDavid du Colombier 
184*9a747e4fSDavid du Colombier void
185*9a747e4fSDavid du Colombier catch(void *, char *msg)
186*9a747e4fSDavid du Colombier {
187*9a747e4fSDavid du Colombier 	fprint(2, "syscall: received note='%s'\n", msg);
188*9a747e4fSDavid du Colombier 	noted(NDFLT);
1893e12c5d1SDavid du Colombier }
190