|
|
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: * COHERENT Version 2.3.37 ! 10: * Copyright (c) 1982, 1983, 1984. ! 11: * An unpublished work by Mark Williams Company, Chicago. ! 12: * All rights reserved. ! 13: * ! 14: * Intel 386 port and extensions (16/32 bit compatibility) ! 15: * Copyright (c) Ciaran O'Donnell, Bievres (FRANCE), 1991 ! 16: * ! 17: * $Log: exec.c,v $ ! 18: * Revision 1.10 92/07/16 16:33:31 hal ! 19: * Kernel #58 ! 20: * ! 21: * Revision 1.9 92/06/11 21:39:19 root ! 22: * Add close on exec. ! 23: * ! 24: * Revision 1.8 92/06/10 12:51:09 hal ! 25: * Do click roundup on call to salloc for eveinit. ! 26: * Assorted cosmetic changes. ! 27: * ! 28: * Revision 1.6 92/02/11 10:09:57 hal ! 29: * Execute shared l.out's now ! 30: * ! 31: * Revision 1.5 92/02/10 18:11:27 hal ! 32: * Ignore SHR bit in l.out's for now. ! 33: * ! 34: * Revision 1.4 92/01/23 18:15:28 hal ! 35: * Add "double sfree" fix from Ciaran. ! 36: * ! 37: * Revision 1.3 92/01/15 11:11:26 hal ! 38: * Remove exlock temporary fix. ! 39: * ! 40: * Revision 1.2 92/01/06 11:58:57 hal ! 41: * Compile with cc.mwc. ! 42: * ! 43: * ! 44: -lgl) */ ! 45: #include <sys/coherent.h> ! 46: #include <acct.h> ! 47: #include <sys/buf.h> ! 48: #include <canon.h> ! 49: #include <sys/con.h> ! 50: #include <errno.h> ! 51: #include <fcntl.h> ! 52: #include <sys/filsys.h> ! 53: #include <sys/ino.h> ! 54: #include <sys/inode.h> ! 55: #include <a.out.h> ! 56: #include <l.out.h> ! 57: #include <sys/proc.h> ! 58: #include <sys/sched.h> ! 59: #include <sys/seg.h> ! 60: #include <signal.h> ! 61: #include <sys/reg.h> ! 62: #include <sys/stat.h> ! 63: #include <sys/fd.h> ! 64: ! 65: /* ! 66: * Pass control to an image in a file. ! 67: * Make sure the format is acceptable. Release ! 68: * the old segments. Read in the new ones. Some special ! 69: * care is taken so that shared and (more important) shared ! 70: * and separated images can be run on the 8086. ! 71: */ ! 72: pexece(np, argp, envp) ! 73: char *np; ! 74: char *argp[]; ! 75: char *envp[]; ! 76: { ! 77: struct xechdr head; ! 78: register INODE *ip; /* Load file INODE */ ! 79: register PROC *pp; /* A cheap copy of SELF */ ! 80: register SEG *segp; ! 81: SEG *ssegp; ! 82: register int i; /* For looping over segments*/ ! 83: register BUF *bp; ! 84: int roundup; ! 85: int shrdsize; ! 86: ! 87: pp = SELF; ! 88: kclear(&head, sizeof(head)); ! 89: if ((ip=exlopen(&head, np, &shrdsize)) == NULL) ! 90: goto done; ! 91: roundup = (shrdsize) & 0xf; ! 92: ssegp = exstack(&head,argp, envp, wdsize()); ! 93: ! 94: if (!ssegp) { ! 95: idetach(ip); ! 96: goto done; ! 97: } ! 98: ! 99: /* ! 100: * At this point the file has been ! 101: * validated as an object module, and the ! 102: * argument list has been built. Release all of ! 103: * the original segments. At this point we have ! 104: * committed to the new image. A "sys exec" that ! 105: * gets an I/O error is doomed. ! 106: * NOTE: User-area segment is NOT released. ! 107: * Segment pointer in proc is erased BEFORE invoking sfree(). ! 108: */ ! 109: ! 110: for ( i = 1; i < NUSEG; ++i ) { ! 111: if ((segp = pp->p_segp[i]) != NULL) { ! 112: pp->p_segp[i] = NULL; ! 113: sfree(segp); ! 114: } ! 115: } ! 116: pp->p_segp[SISTACK] = ssegp; ! 117: ! 118: /* ! 119: * Read in the loadable segments. ! 120: */ ! 121: switch (head.magic) { ! 122: case XMAGIC( I286MAGIC,I_MAGIC ): ! 123: u.u_regl[CS] = SEG_286_UII | R_USR; ! 124: u.u_regl[DS] = SEG_286_UD | R_USR; ! 125: segp = pp->p_segp[SISTEXT] = ssalloc(ip,SFTEXT, ! 126: head.segs[SISTEXT].size); ! 127: if (!exsread(segp, ip, &head.segs[SISTEXT], 0)) { ! 128: goto out; ! 129: } ! 130: segp = ssalloc(ip,0,roundup+ ! 131: head.segs[SIPDATA].size+head.segs[SIBSS].size); ! 132: pp->p_segp[SIPDATA] = segp; ! 133: if (!exsread(segp,ip,&head.segs[SIPDATA],shrdsize)) { ! 134: goto out; ! 135: } ! 136: head.segs[SIPDATA].size += roundup; ! 137: break; ! 138: case XMAGIC( I386MAGIC,Z_MAGIC ): ! 139: u.u_regl[CS] = SEG_386_UI | R_USR; ! 140: u.u_regl[DS] = SEG_386_UD | R_USR; ! 141: segp = pp->p_segp[SISTEXT] = ssalloc(ip,SFTEXT|SFSHRX, ! 142: head.segs[SISTEXT].size); ! 143: if (segp->s_ip==0) { ! 144: if (!exsread(segp, ip, &head.segs[SISTEXT], 0)) { ! 145: goto out; ! 146: } ! 147: segp->s_ip = ip; ! 148: ip->i_refc++; ! 149: } ! 150: segp = ssalloc(ip,0, ! 151: head.segs[SIPDATA].size+head.segs[SIBSS].size); ! 152: pp->p_segp[SIPDATA] = segp; ! 153: if (segp->s_ip==0 && ! 154: !exsread(segp, ip, &head.segs[SIPDATA], 0)) { ! 155: goto out; ! 156: } ! 157: break; ! 158: default: ! 159: panic("pexece"); ! 160: } ! 161: ! 162: u.u_regl[SS] = u.u_regl[ES] = u.u_regl[DS]; ! 163: if (sproto(&head) == 0) { ! 164: goto out; ! 165: } ! 166: ! 167: /* ! 168: * The new image is read in ! 169: * and mapped. Perform the final grunge ! 170: * (set-uid stuff, accounting, loading up ! 171: * registers, etc). ! 172: */ ! 173: u.u_flag &= ~AFORK; ! 174: kkcopy(u.u_direct.d_name, u.u_comm, sizeof(u.u_comm)); ! 175: if (iaccess(ip, IPR) == 0) { /* Can't read ? no dump or trace */ ! 176: pp->p_flags |= PFNDMP; ! 177: pp->p_flags &= ~PFTRAC; ! 178: } ! 179: ! 180: /* ! 181: * Norm says Frank says we need to drop this for db to work. ! 182: */ ! 183: if (iaccess(ip, IPW) == 0) /* Can't write ? no trace */ ! 184: pp->p_flags &= ~PFTRAC; ! 185: ! 186: if ((ip->i_mode&ISUID) != 0) { /* Set user id ? no trace */ ! 187: pp->p_uid = u.u_uid = ip->i_uid; ! 188: pp->p_flags &= ~PFTRAC; ! 189: } ! 190: if ((ip->i_mode&ISGID) != 0) { /* Set group id ? no trace */ ! 191: u.u_gid = ip->i_gid; ! 192: pp->p_flags &= ~PFTRAC; ! 193: } ! 194: for (i=0; i < NUFILE; i++) { ! 195: if (u.u_filep[i]!=NULL && (u.u_filep[i]->f_flag2&FD_CLOEXEC)) { ! 196: fdclose(i); /* close fd on exec bit set */ ! 197: } ! 198: } ! 199: /* ! 200: * Default every signal that is not ignored. ! 201: */ ! 202: for (i=0; i<NSIG; ++i) { ! 203: if (u.u_sfunc[i] != SIG_IGN) { ! 204: u.u_sfunc[i] = SIG_DFL; ! 205: pp->p_dfsig |= ((sig_t) 1) << (i - 1); ! 206: } ! 207: } ! 208: if ((pp->p_flags&PFTRAC) != 0) /* Being traced */ ! 209: sendsig(SIGTRAP, pp); ! 210: idetach(ip); ! 211: msetusr(head.entry, head.initsp); ! 212: ! 213: segload(); ! 214: goto done; ! 215: ! 216: /* ! 217: * We did not make it. ! 218: * Release the INODE for the load ! 219: * file, and return through the "sys exit" ! 220: * code with a "SIGSYS", or with the signal actually received ! 221: * if we are aborting due to interrupted exec. ! 222: */ ! 223: out: ! 224: idetach(ip); ! 225: if (u.u_error == EINTR) ! 226: pexit(nondsig()); ! 227: pexit(SIGSYS); ! 228: ! 229: done: ! 230: return 0; ! 231: } ! 232: ! 233: /* ! 234: * Open an l.out, make sure it is an l.out and executable and return the ! 235: * appropriate information. ! 236: */ ! 237: INODE * ! 238: exlopen(xhp, np, shrds) ! 239: register struct xechdr *xhp; ! 240: char *np; ! 241: int *shrds; ! 242: { ! 243: register INODE *ip; ! 244: int i, nscn, diff, hdrsize; ! 245: register BUF *bp; ! 246: unsigned short magic; ! 247: struct ldheader head; ! 248: struct filehdr fhead; ! 249: struct aouthdr ahead; ! 250: struct scnhdr scnhdr; ! 251: ! 252: /* ! 253: * Make sure the file is really an executable l.out and read the ! 254: * header in. ! 255: */ ! 256: if (ftoi(np, 'r') != 0) ! 257: return (NULL); ! 258: ip = u.u_cdiri; ! 259: if (iaccess(ip, IPE) == 0) { ! 260: idetach(ip); ! 261: return (NULL); ! 262: } ! 263: if ((ip->i_mode&(IPE|IPE<<3|IPE<<6))==0 || (ip->i_mode&IFMT)!=IFREG) { ! 264: u.u_error = EACCES; ! 265: idetach(ip); ! 266: return (NULL); ! 267: } ! 268: if ((bp=vread(ip, (daddr_t)0)) == NULL) ! 269: goto bad; ! 270: /* ! 271: * Copy everything we need from the l.out header and check magic ! 272: * number and machine type. ! 273: */ ! 274: *shrds = 0; /* set return arg shrds nonzero only for shared l.out */ ! 275: kkcopy(bp->b_vaddr, &magic, sizeof(magic)); ! 276: canint(magic); ! 277: switch (magic) { ! 278: case L_MAGIC: /* Coherent 286 format */ ! 279: kkcopy(bp->b_vaddr, &head, sizeof(struct ldheader)); ! 280: canint(head.l_machine); ! 281: if (head.l_machine!=M_8086) ! 282: goto bad; ! 283: for (i=0; i<NXSEG; i++) { ! 284: cansize(head.l_ssize[i]); ! 285: } ! 286: canint(head.l_flag); ! 287: canvaddr(head.l_entry); ! 288: ! 289: /* ! 290: * If a shared and separated image ! 291: * has stuff in segments that makes it impossible ! 292: * to share, give an error immediately so that we don't ! 293: * lose the parent. ! 294: */ ! 295: head.l_flag &= LF_SHR|LF_SEP|LF_KER; ! 296: ! 297: if ((head.l_flag&LF_SEP==0) || (head.l_flag &LF_KER) ! 298: || head.l_ssize[L_PRVI] || head.l_ssize[L_BSSI]) { ! 299: goto bad; ! 300: } ! 301: xhp->magic = XMAGIC( I286MAGIC,I_MAGIC ); ! 302: xhp->entry = head.l_entry; ! 303: ! 304: xhp->segs[SISTEXT].fbase = sizeof(struct ldheader); ! 305: xhp->segs[SISTEXT].mbase = NBPS; ! 306: xhp->segs[SISTEXT].size = head.l_ssize[L_SHRI]; ! 307: ! 308: xhp->segs[SIPDATA].fbase = sizeof(struct ldheader) + ! 309: xhp->segs[SISTEXT].size; ! 310: xhp->segs[SIPDATA].mbase = 0; ! 311: xhp->segs[SIPDATA].size = head.l_ssize[L_SHRD] + ! 312: head.l_ssize[L_PRVD]; ! 313: if (head.l_flag & LF_SHR) ! 314: *shrds = head.l_ssize[L_SHRD]; ! 315: ! 316: xhp->segs[SIBSS].fbase = 0; ! 317: xhp->segs[SIBSS].mbase = xhp->segs[SIPDATA].size; ! 318: xhp->segs[SIBSS].size = head.l_ssize[L_BSSD]; ! 319: ! 320: xhp->segs[SISTACK].mbase = ISP_286; /* size 0, fbase 0 */ ! 321: brelease(bp); ! 322: return ip; ! 323: ! 324: case I386MAGIC: /* ... COFF */ ! 325: kkcopy(bp->b_vaddr, &fhead, sizeof(struct filehdr)); ! 326: hdrsize = sizeof(ahead)+sizeof(fhead); ! 327: if(fhead.f_opthdr!=sizeof (ahead) || !(fhead.f_flags&F_EXEC)|| ! 328: fhead.f_nscns*sizeof(scnhdr) > BSIZE) ! 329: goto bad; ! 330: ! 331: kkcopy(bp->b_vaddr+sizeof(fhead), &ahead, sizeof(ahead)); ! 332: if ((/*ahead.magic!=O_MAGIC && ahead.magic!=N_MAGIC && */ ! 333: ahead.magic!=Z_MAGIC)) ! 334: goto bad; ! 335: ! 336: xhp->magic = XMAGIC( I386MAGIC,ahead.magic ); ! 337: xhp->entry = ahead.entry; ! 338: ! 339: for (i=0; i<fhead.f_nscns; i++) { ! 340: kkcopy(bp->b_vaddr + hdrsize + sizeof(scnhdr)*i, ! 341: &scnhdr, sizeof(scnhdr)); ! 342: switch ((int)(scnhdr.s_flags)) { ! 343: case STYP_INFO: ! 344: continue; ! 345: case STYP_BSS: ! 346: nscn = SIBSS; ! 347: break; ! 348: case STYP_TEXT: ! 349: nscn = SISTEXT; goto common; ! 350: case STYP_DATA: ! 351: nscn = SIPDATA; ! 352: common: ! 353: diff = scnhdr.s_scnptr & (NBPC-1); ! 354: scnhdr.s_vaddr -= diff; ! 355: scnhdr.s_scnptr -= diff; ! 356: scnhdr.s_size += diff; ! 357: break; ! 358: default: ! 359: goto bad; ! 360: } ! 361: ! 362: if (xhp->segs[nscn].size!=0 ! 363: || (unsigned)scnhdr.s_vaddr >= ISP_386) ! 364: goto bad; ! 365: ! 366: xhp->segs[nscn].mbase = scnhdr.s_vaddr; ! 367: xhp->segs[nscn].fbase = scnhdr.s_scnptr; ! 368: xhp->segs[nscn].size = scnhdr.s_size; ! 369: } ! 370: ! 371: if (!xhp->segs[SISTEXT].size || !xhp->segs[SIPDATA].size) ! 372: goto bad; ! 373: ! 374: xhp->entry = ahead.entry; ! 375: if (xhp->entry >= xhp->segs[SISTEXT].size) ! 376: goto bad; ! 377: ! 378: xhp->segs[SISTACK].mbase = ISP_386; /* size 0, fbase 0 */ ! 379: xhp->magic = XMAGIC( I386MAGIC,ahead.magic ); ! 380: brelease(bp); ! 381: return ip; ! 382: default: ! 383: bad: ! 384: brelease(bp); ! 385: u.u_error = ENOEXEC; ! 386: idetach(ip); ! 387: return NULL; ! 388: } ! 389: } ! 390: ! 391: /* ! 392: * Given a segment `sp', read `ss' bytes from the inode `ip' starting ! 393: * at seek address `sa' into offset `so' in the segment. ! 394: * ! 395: * Argument "first" is nonzero only when loading data for l.out - ! 396: * need this because *shared* l.out's need PRVD to be aligned on the next ! 397: * 16 byte boundary after the end of SHRD. So we need to leave a hole ! 398: * between SHRD and PRVD in this case. ! 399: */ ! 400: static SEG * ! 401: exsread(sp, ip, xsp, first) ! 402: register SEG *sp; ! 403: INODE *ip; ! 404: struct xecseg *xsp; ! 405: int first; ! 406: { ! 407: register int ss, sa, so, did; ! 408: int overshoot; ! 409: ! 410: sa = xsp->fbase; ! 411: so = 0; ! 412: ! 413: for (ss = first ? first : xsp->size;; ss -= did) { ! 414: if (!ss) { /* we finished a hunk */ ! 415: /* is there more to read */ ! 416: if (!first || (!(ss = xsp->size - first))) ! 417: break; ! 418: so = (so + 15) & ~15; /* round up */ ! 419: first = 0; /* don't go again */ ! 420: } ! 421: u.u_io.io_seg = IOPHY; ! 422: u.u_io.io_seek = sa; ! 423: u.u_io.io.pbase = MAPIO(sp->s_vmem, so); ! 424: u.u_io.io_flag = 0; ! 425: /* ! 426: * "did" is how many bytes to read in with this request. ! 427: */ ! 428: if (ss >= 4096) ! 429: did = u.u_io.io_ioc = 4096; ! 430: else ! 431: did = u.u_io.io_ioc = ss; ! 432: /* ! 433: * Don't allow incoming data to straddle a 4k segment. ! 434: */ ! 435: overshoot = did + (so & 4095) - 4096; ! 436: if (overshoot > 0) ! 437: did -= overshoot; ! 438: sp->s_lrefc++; ! 439: iread(ip, &u.u_io); ! 440: sp->s_lrefc--; ! 441: if (nondsig()) { ! 442: u.u_error = EINTR; ! 443: break; ! 444: } ! 445: sa += did; ! 446: so += did; ! 447: } ! 448: if (u.u_error == 0) ! 449: return (sp); ! 450: return (NULL); ! 451: } ! 452: ! 453: struct adata { /* Storage for arg and env data */ ! 454: int np; /* Number of pointers in vector */ ! 455: int nc; /* Number of characters in strings */ ! 456: }; ! 457: ! 458: /* ! 459: * Given a pointer to a list of arguments and a pointer to a list of ! 460: * environments, return a stack with the arguments and environments on it. ! 461: */ ! 462: SEG * ! 463: exstack(xhp, argp, envp, wdin) ! 464: register struct xechdr *xhp; ! 465: vaddr_t argp, envp; ! 466: { ! 467: register SEG *sp; /* Stack segment pointer */ ! 468: struct sdata { /* To keep segment pointers */ ! 469: vaddr_t vp; /* Argv[i], envp[i] pointer */ ! 470: vaddr_t cp; /* Argv[i][j], envp[i][j] pointer */ ! 471: } stk; ! 472: struct adata arg, env; ! 473: int chrsz, vecsz, stksz, wdmask, wdout, stkoff, stktop; ! 474: int stkenvp; ! 475: register int i; ! 476: ! 477: /* Validate and evaluate size of args and envs */ ! 478: if (!excount(argp, &arg, wdin) || !excount(envp, &env, wdin)) ! 479: return NULL; ! 480: ! 481: /* Calculate stack size and allocate it */ ! 482: chrsz = roundu(arg.nc + env.nc, sizeof(int)); ! 483: vecsz = (arg.np+1 + env.np+1) * sizeof(long); ! 484: stksz = roundu(vecsz+chrsz+ISTSIZE, NBPC); ! 485: if (stksz > MADSIZE || !(sp = salloc(stksz, SFDOWN))) { ! 486: u.u_error = E2BIG; ! 487: return NULL; ! 488: } ! 489: ! 490: /* Set up target stack */ ! 491: stktop = xhp->segs[SISTACK].mbase; ! 492: stk.cp = stktop - chrsz; ! 493: stk.vp = stktop - chrsz - vecsz; ! 494: stkoff = MAPIO(sp->s_vmem, stksz - stktop); ! 495: u.u_argc = arg.np; ! 496: u.u_argp = stk.vp; ! 497: wdmask = -1; ! 498: if (wdin==sizeof(short)) ! 499: wdmask = (unsigned short)wdmask; ! 500: ! 501: switch (stktop) { ! 502: ! 503: case ISP_386: ! 504: wdout = sizeof(long); ! 505: xhp->initsp = stk.vp - sizeof(long); ! 506: dmaout(sizeof(long), xhp->initsp+stkoff, &arg.np); ! 507: break; ! 508: ! 509: case ISP_286: ! 510: wdout = sizeof(short); ! 511: xhp->initsp = stk.vp - 3*sizeof(short); ! 512: stkenvp = stk.vp + (arg.np+1) * sizeof(short); ! 513: dmaout(sizeof(short), xhp->initsp+stkoff, &arg.np); ! 514: dmaout(sizeof(short), xhp->initsp+sizeof(short)+stkoff, ! 515: &stk.vp); ! 516: dmaout(sizeof(short), xhp->initsp+2*sizeof(short)+stkoff, ! 517: &stkenvp); ! 518: break; ! 519: ! 520: default: ! 521: panic("exstack"); ! 522: ! 523: } ! 524: ! 525: /* Arguments */ ! 526: for (i = 0; i<arg.np; i++, argp += wdin, stk.vp += wdout) { ! 527: dmaout(wdout, stk.vp+stkoff, &stk.cp); ! 528: stk.cp += exarg(stk.cp+stkoff, getupd(argp) & wdmask); ! 529: } ! 530: ! 531: /* skip null word after arguments */ ! 532: stk.vp += wdout; ! 533: ! 534: /* Environments */ ! 535: for (i = 0; i<env.np; i++, envp += wdin, stk.vp += wdout) { ! 536: dmaout(wdout, stk.vp+stkoff, &stk.cp); ! 537: stk.cp += exarg(stk.cp+stkoff, getupd(envp) & wdmask); ! 538: } ! 539: ! 540: return sp; ! 541: } ! 542: ! 543: exarg(out, in) ! 544: vaddr_t in, out; ! 545: { ! 546: char c; ! 547: vaddr_t init_in; ! 548: ! 549: init_in = in; ! 550: do { ! 551: c = getubd(in++); ! 552: dmaout(sizeof(char), out++, &c); ! 553: } while (c); ! 554: return in - init_in; ! 555: } ! 556: ! 557: ! 558: /* ! 559: * Given a pointer to a list of arguments, a pointer to an argument count ! 560: * and a pointer to a byte count, count the #characters/#strigns ! 561: * in the arguments ! 562: */ ! 563: excount(usrvp, adp, wdin) ! 564: register vaddr_t usrvp; ! 565: struct adata *adp; ! 566: { ! 567: register vaddr_t usrcp; ! 568: register int c; ! 569: register unsigned nb; ! 570: register unsigned na; ! 571: int wdmask; ! 572: ! 573: wdmask = -1; ! 574: if (wdin==sizeof(short)) ! 575: wdmask = (unsigned short)wdmask; ! 576: na = nb = 0; ! 577: if (usrvp != NULL) { ! 578: for (;;) { ! 579: usrcp = getupd(usrvp) & wdmask; ! 580: usrvp += wdin; ! 581: if (u.u_error) ! 582: return (0); ! 583: if (usrcp == NULL) ! 584: break; ! 585: na++; ! 586: for (;;) { ! 587: c = getubd(usrcp++); ! 588: if (u.u_error) ! 589: return (0); ! 590: nb++; ! 591: if (c == '\0') ! 592: break; ! 593: } ! 594: } ! 595: } ! 596: adp->np = na; ! 597: adp->nc = nb; ! 598: return (1); ! 599: } ! 600: ! 601: /* ! 602: * Round up a size to a paragraph ! 603: * (mod 16) boundry. ! 604: * This is really mod 512 to make swapping work ! 605: */ ! 606: off_t ! 607: exround(s) ! 608: off_t s; ! 609: { ! 610: return ((s+15)&~0x0F); ! 611: } ! 612: ! 613: pload( np ) ! 614: char * np; ! 615: { ! 616: return -1; ! 617: ! 618: } ! 619: /* ! 620: * Set up the first process, a small programme which will exec ! 621: * the init programme. ! 622: */ ! 623: eveinit() ! 624: { ! 625: SEG *sp; ! 626: register PROC *pp; ! 627: SELF = pp = eprocp; ! 628: /* static struct xechdr xecinit[NUSEG+1] = { {0},{0},{0},{ISP_386}}; */ ! 629: ! 630: /* ! 631: * Allocate, record, initialize code segment, make it executable. ! 632: */ ! 633: if ((sp = salloc(roundu(icodes, NBPC), 0)) == NULL) ! 634: panic("eveinit(code)"); ! 635: pp->p_segp[SIPDATA] = sp; ! 636: ! 637: /* ! 638: * Start process. ! 639: */ ! 640: u.u_argp = 0; ! 641: if (sproto(0) == 0) ! 642: panic("eveinit()"); ! 643: segload(); ! 644: kucopy(icodep, 0, icodes); ! 645: } ! 646: ! 647: /* ! 648: * Given a major number, undo the previous function. ! 649: */ ! 650: puload(m) ! 651: int m; ! 652: { ! 653: register CON *cp; ! 654: register DRV *dp; ! 655: ! 656: dp = &drvl[m]; ! 657: lock(dp->d_gate); ! 658: if (m>=drvn || (cp=dp->d_conp)==NULL) { ! 659: u.u_error = ENXIO; ! 660: goto ret; ! 661: } ! 662: (*cp->c_uload)(); ! 663: if ( ! u.u_error) ! 664: dp->d_conp = NULL; ! 665: ret: ! 666: unlock(dp->d_gate); ! 667: return (0); ! 668: } ! 669:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.