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