|
|
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.