|
|
1.1 root 1: /*
2: * i386/sys1632.c
3: *
4: * This file contains the code for those system calls whose implementation
5: * must vary, according to system call arguments size (16 or 32 bits)
6: *
7: * exec: argv[], envp[] pointers (ingoing and outgoing)
8: * istat:alignment of longs (called by ustat, ufstat in [sys?.c])
9: * ftime:alignment of longs
10: * lseek:argument is a long pointer
11: * dup, dup2: old implementation
12: *
13: * Revised: Fri Jul 16 12:23:39 1993 CDT
14: */
15:
16: #include <common/_limits.h>
17: #include <common/_tricks.h>
18: #include <common/_gregset.h>
19: #include <sys/debug.h>
20:
21: #include <sys/coherent.h>
22: #include <sys/acct.h>
23: #include <sys/buf.h>
24: #include <canon.h>
25: #include <sys/con.h>
26: #include <sys/errno.h>
27: #include <sys/filsys.h>
28: #include <sys/ino.h>
29: #include <sys/inode.h>
30: #include <l.out.h>
31: #include <sys/proc.h>
32: #include <sys/sched.h>
33: #include <sys/seg.h>
34: #include <signal.h>
35: #include <sys/oldstat.h>
36: #include <sys/timeb.h>
37: #include <sys/fd.h>
38:
39: #include <kernel/systab.h>
40:
41:
42: /*
43: * emulate a 16 bit system call
44: * called from trap.c
45: */
46:
47: static char cvtsig [] =
48: {
49: 0,
50: SIGHUP, SIGINT, SIGQUIT, SIGALRM, SIGTERM, SIGPWR,
51: SIGSYS, SIGPIPE, SIGKILL, SIGTRAP, SIGSEGV,
52: SIGEMT, /* SIGDIVE */
53: SIGEMT, /* SIGOVFL */
54: SIGUSR1,
55: SIGUSR2,
56: SIGUSR2
57: };
58:
59: int ostat();
60: int ofstat();
61: int oftime();
62: int upgrp();
63: int ugetuid();
64: int ugetgid();
65: int usysi86();
66: int ulock();
67: int ufcntl();
68: int uexece();
69: int obrk();
70: long oalarm2 ();
71: long otick ();
72:
73:
74: /*
75: * Duplicate a file descriptor number. This has the same calling
76: * sequence as the dup2 system call and even uses the silly DUP2 bit.
77: */
78:
79: coh286dup(ofd, nfd)
80: register unsigned ofd;
81: register unsigned nfd;
82: {
83: register FD *fdp;
84:
85: if ((fdp = fdget (ofd & ~ DUP2)) == NULL)
86: return -1;
87: if ((ofd & DUP2) != 0) {
88: if (nfd >= NOFILE) {
89: SET_U_ERROR (EBADF, "coh286dup ()");
90: return -1;
91: }
92: ofd &= ~ DUP2;
93: if (ofd == nfd)
94: return nfd;
95: if (u.u_filep [nfd] != NULL) {
96: fdclose (nfd);
97: if (u.u_error)
98: return -1;
99: }
100: } else
101: nfd = 0;
102:
103: return fddup (ofd, nfd);
104: }
105:
106:
107: int
108: ostime (timep)
109: time_t * timep;
110: {
111: return ustime (getuwd (timep));
112: }
113:
114:
115: int
116: opipe (pipep)
117: short * pipep;
118: {
119: short res;
120:
121: res = upipe ();
122:
123: putusd (pipep, res);
124: putusd (pipep + 1, u.u_rval2);
125: return 0;
126: }
127:
128:
129: int
130: osetpgrp ()
131: {
132: upgrp (1);
133: }
134:
135: int
136: ogetpgrp ()
137: {
138: upgrp (0);
139: }
140:
141:
142: int
143: ogeteuid ()
144: {
145: (void) ugetuid ();
146: return u.u_rval2;
147: }
148:
149: int
150: ogetegid ()
151: {
152: (void) ugetgid ();
153: return u.u_rval2;
154: }
155:
156:
157: int
158: ounique ()
159: {
160: return usysi86 (SYI86UNEEK);
161: }
162:
163:
164: int
165: okill (pid, signal)
166: short pid;
167: unsigned signal;
168: {
169: if (signal >= __ARRAY_LENGTH (cvtsig)) {
170: SET_U_ERROR (EINVAL, "286 kill ()");
171: return -1;
172: }
173:
174: return ukill (pid, cvtsig [signal]);
175: }
176:
177:
178: __sigfunc_t
179: osignal (signal, func, regsetp)
180: unsigned signal;
181: __sigfunc_t func;
182: gregset_t * regsetp;
183: {
184: if (signal >= __ARRAY_LENGTH (cvtsig)) {
185: SET_U_ERROR (EINVAL, "286 signal ()");
186: return -1;
187: }
188:
189: return usigsys (cvtsig [signal], func, regsetp);
190: }
191:
192:
193: #if __SHRT_BIT != 16
194: # error This code expects 16-bit shorts
195: #endif
196:
197: long
198: olseek (fd, seeklo, seekhi, whence)
199: unsigned fd;
200: unsigned short seeklo;
201: unsigned short seekhi;
202: unsigned whence;
203: {
204: return ulseek (fd, seeklo + (seekhi << 16), whence);
205: }
206:
207:
208: /* msgsys, shmsys, and semsys are not emulated */
209: /* poll is not emulated;NOTE:the code calls putuwd */
210:
211: int
212: oldsys (regsetp)
213: gregset_t * regsetp;
214: {
215: register struct systab *stp;
216: unsigned int callnum;
217: int i;
218: int res;
219: int args [MSACOUNT];
220:
221: u.u_error = 0;
222: callnum = getusd (NBPS + regsetp->_i286._ip - sizeof (short));
223:
224: /*
225: * Check that we are on an INT instruction, and that the fetch did
226: * not cause a memory fault. Note that the magic NBPS number above,
227: * which presumably means "Number of Bytes Per Segment", is how to
228: * get to 286 code.
229: */
230:
231: if (u.u_error || (callnum & 0xFF) != 0xCD)
232: return SIGSYS;
233: callnum = (callnum >> 8) & 0x7F;
234:
235: /* Print out this 286 call number only if tracing is on. */
236: T_PIGGY (0x2, printf ("[%d]", callnum));
237:
238: if (callnum >= __ARRAY_LENGTH (sys286tab))
239: return SIGSYS;
240: stp = sys286tab + callnum;
241:
242: /*
243: * This is crass bullshit which allows fucked code to get away with
244: * not fully intializing a structure which shouldn't even be in the
245: * U area at all.
246: */
247:
248: #if 0
249: u.u_io.io_seg = IOUSR;
250: #endif
251:
252: if (envsave (& u.u_sigenv)) {
253: u.u_error = EINTR;
254: goto done;
255: }
256:
257: i = stp->s_nargs + 1;
258: while (-- i > 0) {
259: args [i - 1] = getusd (regsetp->_i286._usp +
260: i * sizeof (short));
261: }
262:
263: if (u.u_error)
264: return SIGSYS;
265:
266: /*
267: * Perform the system call and collect the return value in "res".
268: */
269:
270: res = __DOSYSCALL (stp->s_nargs, stp->s_func, args, regsetp);
271:
272: if (stp->s_type == __SYSCALL_LONG)
273: regsetp->_i286._dx = res >> 16;
274: else
275: regsetp->_i286._dx = u.u_rval2;
276: regsetp->_i286._ax = res;
277:
278: done:
279: if (u.u_error) {
280: regsetp->_i286._ax = regsetp->_i286._dx = -1;
281: putubd (MUERR, u.u_error);
282: if (u.u_error == EFAULT)
283: return SIGSYS;
284: }
285: return 0;
286: }
287:
288:
289: /*
290: * Given a file descriptor, return a status structure.
291: */
292:
293: ofstat(fd, stp)
294: struct oldstat *stp;
295: {
296: register INODE *ip;
297: register FD *fdp;
298: struct oldstat stat;
299:
300: if ((fdp = fdget (fd)) == NULL)
301: return -1;
302: ip = fdp->f_ip;
303: oistat (ip, & stat);
304: kucopy (& stat, stp, sizeof (stat));
305: return 0;
306: }
307:
308: /*
309: * Return a status structure for the given file name.
310: */
311: ostat(np, stp)
312: char *np;
313: struct oldstat *stp;
314: {
315: register INODE *ip;
316: struct oldstat stat;
317: IO io;
318: struct direct dir;
319:
320: if (ftoi (np, 'r', & io, & dir) != 0)
321: return -1;
322:
323: ip = u.u_cdiri;
324: oistat (ip, & stat);
325:
326: if (kucopy (& stat, stp, sizeof (stat)) != sizeof (stat))
327: SET_U_ERROR (EFAULT, "286 stat ()");
328:
329: idetach(ip);
330: return 0;
331: }
332:
333: /*
334: * Copy the appropriate information from the inode to the stat buffer.
335: */
336: oistat(ip, sbp)
337: register INODE *ip;
338: register struct oldstat *sbp;
339: {
340: sbp->st_dev = ip->i_dev;
341: sbp->st_ino = ip->i_ino;
342: sbp->st_mode = ip->i_mode;
343: sbp->st_nlink = ip->i_nlink;
344: sbp->st_uid = ip->i_uid;
345: sbp->st_gid = ip->i_gid;
346: sbp->st_rdev = NODEV;
347: sbp->st_size = ip->i_size;
348: sbp->st_atime = ip->i_atime;
349: sbp->st_mtime = ip->i_mtime;
350: sbp->st_ctime = ip->i_ctime;
351:
352: switch (ip->i_mode & IFMT) {
353: case IFBLK:
354: case IFCHR:
355: sbp->st_rdev = ip->i_a.i_rdev;
356: sbp->st_size = 0;
357: break;
358:
359: case IFPIPE:
360: sbp->st_size = ip->i_pnc;
361: break;
362: }
363: }
364:
365: /*
366: * Return date and time.
367: */
368:
369: oftime(tbp)
370: struct timeb *tbp;
371: {
372: struct timeb timeb;
373:
374: timeb.time = timer.t_time;
375: /* This should be a machine.h macro to avoid
376: * unnecessary long arithmetic and roundoff errors
377: */
378: timeb.millitm = timer.t_tick*(1000/HZ);
379: timeb.timezone = timer.t_zone;
380: timeb.dstflag = timer.t_dstf;
381:
382: if (kucopy (& timeb, tbp, sizeof (timeb)) != sizeof (timeb))
383: SET_U_ERROR (EFAULT, "286 ftime ()");
384: }
385:
386:
387: /*
388: * Send a SIGALARM signal in `n' clock ticks.
389: */
390:
391: long
392: oalarm2(n)
393: long n;
394: {
395: register PROC * pp = SELF;
396: long s;
397: extern sigalrm ();
398:
399: /*
400: * Calculate time left before current alarm timeout.
401: */
402: s = 0;
403: if (pp->p_alrmtim.t_last != NULL)
404: s = pp->p_alrmtim.t_lbolt - lbolt;
405:
406: /*
407: * Cancel previous alarm [if any], start new alarm [if n != 0].
408: */
409:
410: timeout2 (& pp->p_alrmtim, (long) n, sigalrm, pp);
411:
412: /*
413: * Return time left before previous alarm timeout.
414: */
415: return s;
416: }
417:
418: /*
419: * Return elapsed ticks since system startup.
420: */
421:
422: long
423: otick()
424: {
425: return lbolt;
426: }
427:
428: /*
429: * Cause a signal routine to be executed.
430: * Called from [coh/sig.c]
431: */
432: oldsigstart (n, func, regsetp)
433: __sigfunc_t func;
434: gregset_t * regsetp;
435: {
436: int i;
437: struct {
438: ushort_t sf_signo;
439: ushort_t sf_prev_ip;
440: ushort_t sf_flags;
441: } signal_frame;
442:
443: /*
444: * -1
445: * calculate cvtsig [n]
446: *
447: */
448:
449: signal_frame.sf_signo = n;
450: for (i = 0 ; i < __ARRAY_LENGTH (cvtsig) ; i ++)
451: if (cvtsig [i] == n) {
452: signal_frame.sf_signo = i;
453: break;
454: }
455:
456: signal_frame.sf_prev_ip = regsetp->_i286._ip;
457: signal_frame.sf_flags = regsetp->_i286._flags;
458:
459: /*
460: * Turn off single-stepping in signal handler.
461: */
462:
463: regsetp->_i286._flags &= ~ MFTTB;
464: regsetp->_i286._ip = (ushort_t) func;
465: regsetp->_i286._usp -= sizeof (signal_frame);
466:
467: i = kucopy (& signal_frame, regsetp->_i286._usp,
468: sizeof (signal_frame));
469: ASSERT (i == sizeof (signal_frame));
470: }
471:
472: /*
473: * obrk()
474: *
475: * Argument is the new linear space value for the end of the PDATA segment.
476: * As was done in COH286, arg of zero asks for the old upper limit.
477: */
478: obrk (cp)
479: unsigned cp;
480: {
481: register int res;
482:
483: /*
484: * If cp nonzero
485: * resize user data segment
486: * else
487: * just give info - current brk address
488: */
489:
490: if (cp)
491: res = ubrk (cp);
492: else
493: res = u.u_segl [SIPDATA].sr_base +
494: SELF->p_segp [SIPDATA]->s_size;
495:
496: return res;
497: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.