xref: /plan9/sys/src/cmd/syscall/syscall.c (revision 1c91605c2ba4c4f48e9e82b6f1ed88197f96bb37)
1 #include <u.h>
2 #include <libc.h>
3 #include <sys.h>
4 #include <fcall.h>
5 
6 char	buf[1048576];
7 #define	NARG	5
8 uintptr	arg[NARG];
9 
10 /* system calls not defined in libc.h */
11 int	sysr1(void);
12 int	_stat(char*, char*);
13 int	_fstat(int, char*);
14 int	_errstr(char*);
15 int	_wstat(char*, char*);
16 int	_fwstat(int, char*);
17 int	_read(int, void*, int);
18 int	_write(int, void*, int);
19 int	_read9p(int, void*, int);
20 int	_write9p(int, void*, int);
21 int	brk_(void*);
22 int	_nfstat(int, void*, int);
23 int	_nstat(char*, void*, int);
24 int	_nfwstat(int, void*, int);
25 int	_nwstat(char*, void*, int);
26 int	_fsession(char*, void*, int);
27 int	_mount(int, char*, int, char*);
28 int	_wait(void*);
29 
30 struct{
31 	char	*name;
32 	int	(*func)(...);
33 }tab[]={
34 #include "tab.h"
35 	0,		0
36 };
37 
38 uintptr parse(char *);
39 void catch(void*, char*);
40 
41 char*
xctime(ulong t)42 xctime(ulong t)
43 {
44 	char *buf, *s;
45 
46 	s = ctime(t);
47 	s[strlen(s)-1] = '\0';	/* remove newline */
48 	buf = malloc(512);
49 	if(buf == nil)
50 		sysfatal("can't malloc: %r");
51 	snprint(buf, 512, "%s (%lud)", s, t);
52 	return buf;
53 }
54 
55 
56 char*
lstime(long l)57 lstime(long l)
58 {
59 	static char buf[32];
60 	char *t;
61 	long clk;
62 
63 	clk = time(0);
64 	t = ctime(l);
65 	/* 6 months in the past or a day in the future */
66 	if(l<clk-180L*24*60*60 || clk+24L*60*60<l){
67 		memmove(buf, t+4, 7);		/* month and day */
68 		memmove(buf+7, t+23, 5);		/* year */
69 	}else
70 		memmove(buf, t+4, 12);		/* skip day of week */
71 	buf[12] = 0;
72 	return buf;
73 }
74 
75 void
main(int argc,char * argv[])76 main(int argc, char *argv[])
77 {
78 	int i, j, c;
79 	int oflag, xflag, sflag;
80 	vlong r;
81 	Dir d;
82 	char strs[1024];
83 	char ebuf[1024];
84 
85 	fmtinstall('M', dirmodefmt);
86 
87 	oflag = 0;
88 	xflag = 0;
89 	sflag = 0;
90 	ARGBEGIN{
91 	case 'o':
92 		oflag++;
93 		break;
94 	case 's':
95 		sflag++;
96 		break;
97 	case 'x':
98 		xflag++;
99 		break;
100 	default:
101 		goto Usage;
102 	}ARGEND
103 	if(argc<1 || argc>1+NARG){
104     Usage:
105 		fprint(2, "usage: syscall [-ox] entry [args; buf==1MB buffer]\n");
106 		fprint(2, "\tsyscall write 1 hello 5\n");
107 		fprint(2, "\tsyscall -o errstr buf 1024\n");
108 		fprint(2, "\tsyscall -[xs] stat file buf 1024\n");
109 		exits("usage");
110 	}
111 	for(i=1; i<argc; i++)
112 		arg[i-1] = parse(argv[i]);
113 	notify(catch);
114 	for(i=0; tab[i].name; i++)
115 		if(strcmp(tab[i].name, argv[0])==0){
116 			/* special case for seek, pread, pwrite; vlongs are problematic */
117 			if(strcmp(argv[0], "seek") == 0)
118 				r=seek(arg[0], strtoll(argv[2], 0, 0), arg[2]);
119 			else if(strcmp(argv[0], "pread") == 0)
120 				r=pread(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0));
121 			else if(strcmp(argv[0], "pwrite") == 0)
122 				r=pwrite(arg[0], (void*)arg[1], arg[2], strtoll(argv[4], 0, 0));
123 			else
124 				r=(*tab[i].func)(arg[0], arg[1], arg[2], arg[3], arg[4]);
125 			if(r == -1){
126 				errstr(ebuf, sizeof ebuf);
127 				fprint(2, "syscall: return %lld, error:%s\n", r, ebuf);
128 			}else{
129 				ebuf[0] = 0;
130 				fprint(2, "syscall: return %lld, no error\n", r);
131 			}
132 			if(oflag)
133 				print("%s\n", buf);
134 			if(xflag){
135 				for(j=0; j<r; j++){
136 					if(j%16 == 0)
137 						print("%.4x\t", j);
138 					c = buf[j]&0xFF;
139 					if('!'<=c && c<='~')
140 						print(" %c ", c);
141 					else
142 						print("%.2ux ", c);
143 					if(j%16 == 15)
144 						print("\n");
145 				}
146 				print("\n");
147 			}
148 			if(sflag && r > 0){
149 				r = convM2D((uchar*)buf, r, &d, strs);
150 				if(r <= BIT16SZ)
151 					print("short stat message\n");
152 				else{
153 					print("[%s] ", d.muid);
154 					print("(%.16llux %lud %.2ux) ", d.qid.path, d.qid.vers, d.qid.type);
155 					print("%M (%luo) ", d.mode, d.mode);
156 					print("%c %d ", d.type, d.dev);
157 					print("%s %s ", d.uid, d.gid);
158 					print("%lld ", d.length);
159 					print("%s ", lstime(d.mtime));
160 					print("%s\n", d.name);
161 					print("\tmtime: %s\n\tatime: %s\n", xctime(d.mtime), xctime(d.atime));
162 				}
163 			}
164 			exits(ebuf);
165 		}
166 	fprint(2, "syscall: %s not known\n", argv[0]);
167 	exits("unknown");
168 }
169 
170 uintptr
parse(char * s)171 parse(char *s)
172 {
173 	char *t;
174 	uintptr l;
175 
176 	if(strcmp(s, "buf") == 0)
177 		return (uintptr)buf;
178 
179 	l = strtoull(s, &t, 0);
180 	if(t>s && *t==0)
181 		return l;
182 	return (uintptr)s;
183 }
184 
185 void
catch(void *,char * msg)186 catch(void *, char *msg)
187 {
188 	fprint(2, "syscall: received note='%s'\n", msg);
189 	noted(NDFLT);
190 }
191