|
|
1.1 root 1: /* (lgl-
2: * The information contained herein is a trade secret of Mark Williams
3: * Company, and is confidential information. It is provided under a
4: * license agreement, and may be copied or disclosed only under the
5: * terms of that agreement. Any reproduction or disclosure of this
6: * material without the express written authorization of Mark Williams
7: * Company or persuant to the license agreement is unlawful.
8: *
9: * Intel 386 port and extensions (16/32 bit compatibility)
10: * Copyright (c) Ciaran O'Donnell, Bievres (FRANCE), 1991
11: -lgl)
12: */
13:
14: /*
15: * i386/sys1632.c
16: *
17: * This file contains the code for those system calls whose implementation
18: * must vary, according to system call arguments size (16 or 32 bits)
19: *
20: * exec: argv[], envp[] pointers (ingoing and outgoing)
21: * istat:alignment of longs (called by ustat, ufstat in [sys?.c])
22: * ftime:alignment of longs
23: * lseek:argument is a long pointer
24: * dup, dup2: old implementation
25: *
26: * Revised: Fri Jun 11 06:36:06 1993 CDT
27: */
28: #include <sys/coherent.h>
29: #include <sys/acct.h>
30: #include <sys/buf.h>
31: #include <canon.h>
32: #include <sys/con.h>
33: #include <errno.h>
34: #include <sys/filsys.h>
35: #include <sys/ino.h>
36: #include <sys/inode.h>
37: #include <l.out.h>
38: #include <sys/proc.h>
39: #include <sys/sched.h>
40: #include <sys/seg.h>
41: #include <signal.h>
42: #include <sys/systab.h>
43: #include <sys/oldstat.h>
44: #include <sys/timeb.h>
45: #include <sys/fd.h>
46:
47: /*
48: * emulate a 16 bit system call
49: * called from trap.c
50: */
51:
52: char cvtsig[] =
53: {
54: 0,
55: SIGHUP, SIGINT, SIGQUIT, SIGALRM, SIGTERM, SIGPWR,
56: SIGSYS, SIGPIPE, SIGKILL, SIGTRAP, SIGSEGV,
57: SIGEMT, /* SIGDIVE */
58: SIGEMT, /* SIGOVFL */
59: SIGUSR1,
60: SIGUSR2,
61: SIGUSR2,
62: -1
63: };
64:
65: int ostat();
66: int ofstat();
67: int oftime();
68: int upgrp();
69: int ugetuid();
70: int ugetgid();
71: int usysi86();
72: int ulock();
73: int ufcntl();
74: int uexece();
75: int fddup();
76: int obrk();
77:
78: static long ualarm2();
79: static long utick();
80:
81: int
82: oldsys()
83: {
84: register struct systab *stp;
85: register int syscall, callnum, nargs;
86: int l;
87: int (*func)();
88: int swap, res;
89: int temp;
90:
91: u.u_error = 0;
92: syscall = getuwd(NBPS+u.u_regl[EIP]-sizeof(short));
93: if (u.u_error || (syscall&0xFF) != 0xCD)
94: return SIGSYS;
95: callnum = (syscall>>8) & 0x7F;
96: /* Print out this 286 call number only if tracing is on. */
97: T_PIGGY(0x2, printf("[%d]", callnum););
98:
99: stp = &sysitab[callnum];
100: if (callnum >= NMICALL)
101: return SIGSYS;
102: u.u_io.io_seg = IOUSR;
103: if (envsave(&u.u_sigenv)) {
104: u.u_error = EINTR;
105: goto done;
106: }
107:
108: func = stp->s_func;
109: swap = 0;
110: nargs = stp->s_nargs;
111:
112: for (l=0; l<nargs; l++)
113: u.u_args[l] = (unsigned short)
114: getuwd(u.u_regl[UESP]+(l+1)*sizeof(short));
115:
116: switch (callnum) {
117: case 7:
118: nargs = 1;
119: goto update;
120: case 17: /* brk(0) was used in old Coherent */
121: func = obrk;
122: break;
123: case 18: /* stat and fstat have 32 bit alignment now */
124: func = ostat;
125: break;
126: case 25: /* ustime() 386 takes a value, not a ptr */
127: u.u_args[0] = getuwd(u.u_args[0]);
128: break;
129: case 28:
130: func = ofstat;
131: break;
132: case 35: /* ftime system call has gone away */
133: func = oftime;
134: nargs = 1;
135: goto update;
136: case 41: /* kludge second argument for dup2() */
137: nargs = 2;
138: func = fddup;
139: goto update;
140: case 42: /* pipe - store thru pointer */
141: nargs = 1;
142: goto update;
143: case 72: /* ualarm2 and utick have disappeared */
144: func = ualarm2;
145: nargs = 1;
146: goto update;
147: case 73:
148: func = utick;
149: nargs = 1;
150: goto update;
151: case 62: /* setpgrp */
152: u.u_args[0] = 1;
153: nargs = 1;
154: func = upgrp;
155: break;
156: case 63: /* getpgrp */
157: u.u_args[0] = 0;
158: nargs = 1;
159: func = upgrp;
160: break;
161: case 24: /* getuid and geteuid are together now */
162: case 57:
163: swap = callnum==57;
164: func = ugetuid;
165: break;
166: case 47:
167: case 56: /* getgid & getegid are together now */
168: swap = callnum==56;
169: func = ugetgid;
170: break;
171: case 45: /* unique is a sys-86 call now */
172: func = usysi86;
173: u.u_args[0] = SYI86UNEEK;
174: nargs = 1;
175: break;
176: case 37: /* kill - signal#'s have changed */
177: u.u_args[0] = (signed short) u.u_args[0]; /* Sign extend pid. */
178: u.u_args[1] = cvtsig[u.u_args[1]];
179: break;
180: case 48: /* signal - signal#'s have changed */
181: u.u_args[0] = cvtsig[u.u_args[0]];
182: break;
183: case 53: /* ulock has moved */
184: func = ulock;
185: nargs = 1;
186: goto update;
187: case 66: /* fcntl has moved */
188: func = ufcntl;
189: nargs = 3;
190: goto update;
191: case 11: /* exec has only one entry point now */
192: func = uexece;
193: nargs = 3;
194: goto update;
195: case 19: /* seek offset is 32 bits now ; shift */
196: u.u_args[1] |= u.u_args[2]<<16;
197: u.u_args[2] = (unsigned short)
198: getuwd(u.u_regl[UESP]+4*sizeof(short));
199: break;
200: update:
201: for (l=0; l<nargs; l++)
202: u.u_args[l] = (unsigned short)
203: getuwd(u.u_regl[UESP]+(l+1)*sizeof(short));
204: break;
205: }
206:
207: if (u.u_error)
208: return SIGSYS;
209:
210: res = (*func)(u.u_args[0], u.u_args[1], u.u_args[2], u.u_args[3],
211: u.u_args[4], u.u_args[5]);
212: if (swap)
213: res = u.u_rval2;
214:
215: switch (callnum) {
216: case 7: /* wait - must store u_rval2 thru pointer */
217: if (u.u_args[0]) {
218: putubd(u.u_args[0], u.u_rval2);
219: putubd(u.u_args[0]+1, u.u_rval2>>8);
220: }
221: break;
222: case 19: /* lseek - upper 16 bits of result in dx */
223: u.u_rval2 = res >> 16;
224: break;
225: case 42: /* pipe - store thru pointer */
226: putubd(u.u_args[0], res);
227: putubd(u.u_args[0]+1, res>>8);
228: putubd(u.u_args[0]+2, u.u_rval2);
229: putubd(u.u_args[0]+3, u.u_rval2>>8);
230: res = 0;
231: break;
232: default:
233: /* msgsys, shmsys, and semsys are not emulated */
234: /* poll is not emulated;NOTE:the code calls putuwd */
235: ;
236: }
237: u.u_regl[EAX] = res;
238: u.u_regl[EDX] = u.u_rval2;
239: done:
240: if (u.u_error) {
241: u.u_regl[EAX] = u.u_regl[EDX] = -1;
242: putubd(MUERR, u.u_error);
243: if (u.u_error == EFAULT)
244: return SIGSYS;
245: }
246: return 0;
247: }
248:
249: /*
250: * Given a file descriptor, return a status structure.
251: */
252: ofstat(fd, stp)
253: struct oldstat *stp;
254: {
255: register INODE *ip;
256: register FD *fdp;
257: struct oldstat stat;
258:
259: if ((fdp=fdget(fd)) == NULL)
260: return;
261: ip = fdp->f_ip;
262: oistat(ip, &stat);
263: kucopy(&stat, stp, sizeof(stat));
264: return (0);
265: }
266:
267: /*
268: * Return a status structure for the given file name.
269: */
270: ostat(np, stp)
271: char *np;
272: struct oldstat *stp;
273: {
274: register INODE *ip;
275: struct oldstat stat;
276:
277: if (ftoi(np, 'r') != 0)
278: return;
279: ip = u.u_cdiri;
280: oistat(ip, &stat);
281: kucopy(&stat, stp, sizeof(stat));
282: idetach(ip);
283: return 0;
284: }
285:
286: /*
287: * Copy the appropriate information from the inode to the stat buffer.
288: */
289: oistat(ip, sbp)
290: register INODE *ip;
291: register struct oldstat *sbp;
292: {
293: sbp->st_dev = ip->i_dev;
294: sbp->st_ino = ip->i_ino;
295: sbp->st_mode = ip->i_mode;
296: sbp->st_nlink = ip->i_nlink;
297: sbp->st_uid = ip->i_uid;
298: sbp->st_gid = ip->i_gid;
299: sbp->st_rdev = NODEV;
300: sbp->st_size = ip->i_size;
301: sbp->st_atime = ip->i_atime;
302: sbp->st_mtime = ip->i_mtime;
303: sbp->st_ctime = ip->i_ctime;
304: switch (ip->i_mode&IFMT) {
305: case IFBLK:
306: case IFCHR:
307: sbp->st_rdev = ip->i_a.i_rdev;
308: sbp->st_size = 0;
309: break;
310: case IFPIPE:
311: sbp->st_size = ip->i_pnc;
312: break;
313: }
314: }
315:
316: /*
317: * Return date and time.
318: */
319: oftime(tbp)
320: struct timeb *tbp;
321: {
322: struct timeb timeb;
323:
324: timeb.time = timer.t_time;
325: /* This should be a machine.h macro to avoid
326: * unnecessary long arithmetic and roundoff errors
327: */
328: timeb.millitm = timer.t_tick*(1000/HZ);
329: timeb.timezone = timer.t_zone;
330: timeb.dstflag = timer.t_dstf;
331: kucopy(&timeb, tbp, sizeof(timeb));
332: }
333:
334: /*
335: * Send a SIGALARM signal in `n' clock ticks.
336: */
337: long
338: ualarm2(n)
339: long n;
340: {
341: register PROC * pp = SELF;
342: long s;
343: extern sigalrm();
344:
345: /*
346: * Calculate time left before current alarm timeout.
347: */
348: s = 0;
349: if (pp->p_alrmtim.t_last != NULL)
350: s = pp->p_alrmtim.t_lbolt - lbolt;
351:
352: /*
353: * Cancel previous alarm [if any], start new alarm [if n != 0].
354: */
355: timeout2(&pp->p_alrmtim, (long) n, sigalrm, pp);
356:
357: /*
358: * Return time left before previous alarm timeout.
359: */
360: return(s);
361: }
362:
363: /*
364: * Return elapsed ticks since system startup.
365: */
366: long
367: utick()
368: {
369: return(lbolt);
370: }
371:
372: /*
373: * Cause a signal routine to be executed.
374: * Called from [coh/sig.c]
375: */
376: oldsigstart(n, f)
377: {
378: int i, n1;
379: register int usp;
380:
381: usp = u.u_regl[UESP];
382:
383: /*
384: * -1
385: * calculate cvtsig [n]
386: *
387: */
388: n1 = n;
389: for (i=0; cvtsig[i]>=0; i++)
390: if (cvtsig[i]==n)
391: n1 = i;
392:
393: putuwd(usp-3*sizeof(short), n1);
394: putuwd(usp-2*sizeof(short), u.u_regl[EIP]);
395: putubd(usp-2, u.u_regl[EFL]);
396: putubd(usp-1, u.u_regl[EFL]>>8);
397: u.u_regl[EFL] &= ~MFTTB;
398: u.u_regl[EIP] = f;
399: u.u_regl[UESP] -= 3*sizeof(short);
400: if (n != SIGTRAP)
401: u.u_sfunc[n-1] = SIG_DFL;
402: }
403:
404: /*
405: * Duplicate a file descriptor number. This has the same calling
406: * sequence as the dup2 system call and even uses the silly DUP2 bit.
407: */
408: fddup(ofd, nfd)
409: register unsigned ofd;
410: register unsigned nfd;
411: {
412: register FD *fdp;
413:
414: if ((fdp=fdget(ofd&~DUP2)) == NULL)
415: return (-1);
416: if ((ofd&DUP2) != 0) {
417: if (nfd >= NOFILE) {
418: u.u_error = EBADF;
419: return (-1);
420: }
421: ofd &= ~DUP2;
422: if (ofd == nfd)
423: return (nfd);
424: if (u.u_filep[nfd] != NULL) {
425: fdclose(nfd);
426: if (u.u_error)
427: return (-1);
428: }
429: } else {
430: for (nfd=0; nfd<NOFILE; nfd++)
431: if (u.u_filep[nfd] == NULL)
432: break;
433: if (nfd == NOFILE) {
434: u.u_error = EMFILE;
435: return (-1);
436: }
437: }
438: u.u_filep[nfd] = fdp;
439: fdp->f_refc++;
440: return (nfd);
441: }
442:
443: /*
444: * obrk()
445: *
446: * Argument is the new linear space value for the end of the PDATA segment.
447: * As was done in COH286, arg of zero asks for the old upper limit.
448: */
449: obrk(cp)
450: long cp;
451: {
452: register int res;
453:
454: cp &= 0xffff; /* Ward off sign extension problems with cp. */
455:
456: /*
457: * If cp nonzero
458: * resize user data segment
459: * else
460: * just give info - current brk address
461: */
462: if (cp)
463: res = ubrk(cp);
464: else
465: res = u.u_segl[SIPDATA].sr_base + SELF->p_segp[SIPDATA]->s_size;
466:
467: return res;
468: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.