1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tc.os.c,v 3.0 1991/07/05 00:05:11 christos Exp $ */ 2: /* 3: * tc.os.c: OS Dependent builtin functions 4: */ 5: /*- 6: * Copyright (c) 1980, 1991 The Regents of the University of California. 7: * All rights reserved. 8: * 9: * Redistribution and use in source and binary forms, with or without 10: * modification, are permitted provided that the following conditions 11: * are met: 12: * 1. Redistributions of source code must retain the above copyright 13: * notice, this list of conditions and the following disclaimer. 14: * 2. Redistributions in binary form must reproduce the above copyright 15: * notice, this list of conditions and the following disclaimer in the 16: * documentation and/or other materials provided with the distribution. 17: * 3. All advertising materials mentioning features or use of this software 18: * must display the following acknowledgement: 19: * This product includes software developed by the University of 20: * California, Berkeley and its contributors. 21: * 4. Neither the name of the University nor the names of its contributors 22: * may be used to endorse or promote products derived from this software 23: * without specific prior written permission. 24: * 25: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35: * SUCH DAMAGE. 36: */ 37: #include "config.h" 38: #if !defined(lint) && !defined(pdp11) 39: static char *rcsid() 40: { return "$Id: tc.os.c,v 3.0 1991/07/05 00:05:11 christos Exp $"; } 41: #endif 42: 43: #include "sh.h" 44: #include "ed.h" 45: #include "ed.defns.h" /* for the function names */ 46: 47: #ifdef titan 48: int end; 49: #endif /* titan */ 50: 51: /*** 52: *** MACH 53: ***/ 54: 55: #ifdef MACH 56: /* dosetpath -- setpath built-in command 57: * 58: ********************************************************************** 59: * HISTORY 60: * 08-May-88 Richard Draves (rpd) at Carnegie-Mellon University 61: * Major changes to remove artificial limits on sizes and numbers 62: * of paths. 63: * 64: ********************************************************************** 65: */ 66: 67: #ifdef MACH 68: static Char STRCPATH[] = {'C', 'P', 'A', 'T', 'H', '\0'}; 69: static Char STRLPATH[] = {'L', 'P', 'A', 'T', 'H', '\0'}; 70: static Char STRMPATH[] = {'M', 'P', 'A', 'T', 'H', '\0'}; 71: static Char STREPATH[] = {'E', 'P', 'A', 'T', 'H', '\0'}; 72: #endif /* MACH */ 73: 74: static Char *syspaths[] = {STRPATH, STRCPATH, STRLPATH, STRMPATH, STREPATH, 0}; 75: #define LOCALSYSPATH "/usr/cs" 76: 77: void 78: dosetpath(arglist) 79: Char **arglist; 80: { 81: extern char *getenv(); 82: 83: Char **pathvars, **cmdargs; 84: Char **paths; 85: char **spaths, **cpaths, **cmds; 86: char *tcp; 87: unsigned int npaths, ncmds; 88: int i, sysflag; 89: 90: for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++); 91: npaths = i - 1; 92: 93: cmdargs = &arglist[i]; 94: for (; arglist[i]; i++); 95: ncmds = i - npaths - 1; 96: 97: if (npaths) { 98: sysflag = 0; 99: pathvars = &arglist[1]; 100: } 101: else { 102: sysflag = 1; 103: npaths = (sizeof syspaths / sizeof *syspaths) - 1; 104: pathvars = syspaths; 105: } 106: 107: /* note that npaths != 0 */ 108: 109: spaths = (char **) xmalloc(npaths * sizeof *spaths); 110: setzero((char *) spaths, npaths * sizeof *spaths); 111: paths = (Char **) xmalloc((npaths + 1) * sizeof *paths); 112: setzero((char *) paths, (npaths + 1) * sizeof *paths); 113: cpaths = (char **) xmalloc((npaths + 1) * sizeof *cpaths); 114: setzero((char *) cpaths, (npaths + 1) * sizeof *cpaths); 115: cmds = (char **) xmalloc((ncmds + 1) * sizeof *cmds); 116: setzero((char *) cmds, (ncmds + 1) * sizeof *cmds); 117: for (i = 0; i < npaths; i++) { 118: char *val = getenv(short2str(pathvars[i])); 119: 120: if (val == NULL) 121: val = ""; 122: 123: spaths[i] = xmalloc((Strlen(pathvars[i]) + strlen(val) 124: + 2) * sizeof **spaths); 125: (void) strcpy(spaths[i], short2str(pathvars[i])); 126: (void) strcat(spaths[i], "="); 127: (void) strcat(spaths[i], val); 128: cpaths[i] = spaths[i]; 129: } 130: 131: for (i = 0; i < ncmds; i++) { 132: Char *val = globone(cmdargs[i], G_ERROR); 133: 134: if (val == NOSTR) 135: goto abortpath; 136: cmds[i] = xmalloc(Strlen(val) + 1); 137: (void) strcpy(cmds[i], short2str(val)); 138: } 139: 140: if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) { 141: abortpath: 142: if (spaths) { 143: for (i = 0; i < npaths; i++) 144: if (spaths[i]) 145: xfree((ptr_t) spaths[i]); 146: xfree((ptr_t) spaths); 147: } 148: if (paths) { 149: for (i = 0; i < npaths; i++) 150: if (paths[i]) 151: xfree((ptr_t) paths[i]); 152: xfree((ptr_t) paths); 153: } 154: if (cpaths) 155: xfree((ptr_t) cpaths); 156: if (cmds) { 157: for (i = 0; i < ncmds; i++) 158: if (cmds[i]) 159: xfree((ptr_t) cmds[i]); 160: xfree((ptr_t) cmds); 161: } 162: 163: for (i = 0; i < npaths; i++) { 164: paths[i] = SAVE(cpaths[i]); 165: xfree((ptr_t) cpaths[i]); 166: } 167: return; 168: } 169: 170: for (i = 0; i < npaths; i++) { 171: Char *val; 172: 173: for (val = paths[i]; val && *val && *val != '='; val++); 174: if (val && *val == '=') { 175: *val++ = '\0'; 176: setenv(paths[i], val); 177: if (Strcmp(paths[i], STRPATH) == 0) { 178: importpath(val); 179: if (havhash) 180: dohash(); 181: } 182: *--val = '='; 183: } 184: } 185: } 186: #endif /* MACH */ 187: 188: /*** 189: *** AIX 190: ***/ 191: #ifdef TCF 192: /* VARARGS *//* ARGSUSED */ 193: void 194: dogetxvers(v) 195: Char **v; 196: { 197: char xvers[MAXPATHLEN]; 198: 199: if (getxvers(xvers, MAXPATHLEN) == -1) 200: stderror(ERR_SYSTEM, "getxvers", strerror(errno)); 201: xprintf("%s\n", xvers); 202: flush(); 203: } 204: 205: void 206: dosetxvers(v) 207: Char **v; 208: { 209: char *xvers; 210: 211: ++v; 212: if (!*v || *v[0] == '\0') 213: xvers = ""; 214: else 215: xvers = short2str(*v); 216: if (setxvers(xvers) == -1) 217: stderror(ERR_SYSTEM, "setxvers", strerror(errno)); 218: } 219: 220: #include <sf.h> 221: #ifdef _AIXPS2 222: # define XC_PDP11 0x01 223: # define XC_23 0x02 224: # define XC_Z8K 0x03 225: # define XC_8086 0x04 226: # define XC_68K 0x05 227: # define XC_Z80 0x06 228: # define XC_VAX 0x07 229: # define XC_16032 0x08 230: # define XC_286 0x09 231: # define XC_386 0x0a 232: # define XC_S370 0x0b 233: #else 234: # include <sys/x.out.h> 235: #endif /* _AIXPS2 */ 236: 237: static struct xc_cpu_t { 238: short xc_id; 239: char *xc_name; 240: } xcpu[] = 241: { 242: { XC_PDP11, "pdp11" }, 243: { XC_23, "i370" }, 244: { XC_Z8K, "z8000" }, 245: { XC_8086, "i86" }, 246: { XC_68K, "mc68000" }, 247: { XC_Z80, "x80" }, 248: { XC_VAX, "vax" }, 249: { XC_16032, "ns16032" }, 250: { XC_286, "i286" }, 251: { XC_386, "i386" }, 252: { XC_S370, "xa370" }, 253: { 0, NULL } 254: }; 255: 256: /* 257: * our local hack table, stolen from x.out.h 258: */ 259: static char * 260: getxcode(xcid) 261: short xcid; 262: { 263: int i; 264: 265: for (i = 0; xcpu[i].xc_name != NULL; i++) 266: if (xcpu[i].xc_id == xcid) 267: return (xcpu[i].xc_name); 268: return (NULL); 269: } 270: 271: static short 272: getxid(xcname) 273: char *xcname; 274: { 275: int i; 276: 277: for (i = 0; xcpu[i].xc_name != NULL; i++) 278: if (strcmp(xcpu[i].xc_name, xcname) == 0) 279: return (xcpu[i].xc_id); 280: return ((short) -1); 281: } 282: 283: 284: void 285: dogetspath(v) 286: Char **v; 287: { 288: int i, j; 289: sitepath_t p[MAXSITE]; 290: struct sf *st; 291: static char *local = "LOCAL "; 292: 293: if ((j = getspath(p, MAXSITE)) == -1) 294: stderror(ERR_SYSTEM, "getspath", strerror(errno)); 295: for (i = 0; i < j && (p[i] & SPATH_CPU) != NOSITE; i++) { 296: if (p[i] & SPATH_CPU) { 297: if ((p[i] & SPATH_MASK) == NULLSITE) 298: xprintf(local); 299: else if ((st = sfxcode((short) (p[i] & SPATH_MASK))) != NULL) 300: xprintf("%s ", st->sf_ctype); 301: else { 302: char *xc = getxcode(p[i] & SPATH_MASK); 303: 304: if (xc != NULL) 305: xprintf("%s ", xc); 306: else 307: xprintf("*cpu %d* ", (int) (p[i] & SPATH_MASK)); 308: /* 309: * BUG in the aix code... needs that cause if 310: * sfxcode fails once it fails for ever 311: */ 312: endsf(); 313: } 314: } 315: else { 316: if (p[i] == NULLSITE) 317: xprintf(local); 318: else if ((st = sfnum(p[i])) != NULL) 319: xprintf("%s ", st->sf_sname); 320: else 321: xprintf("*site %d* ", (int) (p[i] & SPATH_MASK)); 322: } 323: } 324: xprintf("\n"); 325: flush(); 326: } 327: 328: void 329: dosetspath(v) 330: Char **v; 331: { 332: int i; 333: short j; 334: char *s; 335: sitepath_t p[MAXSITE]; 336: struct sf *st; 337: 338: for (i = 0, v++; *v && *v[0] != '\0'; v++, i++) { 339: s = short2str(*v); 340: if (Isdigit(*s)) 341: p[i] = atoi(s); 342: else if (strcmp(s, "LOCAL") == 0) 343: p[i] = NULLSITE; 344: else if ((st = sfctype(s)) != NULL) 345: p[i] = SPATH_CPU | st->sf_ccode; 346: else if ((j = getxid(s)) != -1) 347: p[i] = SPATH_CPU | j; 348: else if ((st = sfname(s)) != NULL) 349: p[i] = st->sf_id; 350: else { 351: setname(s); 352: stderror(ERR_NAME | ERR_STRING, "Bad cpu/site name"); 353: } 354: if (i == MAXSITE - 1) 355: stderror(ERR_NAME | ERR_STRING, "Site path too long"); 356: } 357: if (setspath(p, i) == -1) 358: stderror(ERR_SYSTEM, "setspath", strerror(errno)); 359: } 360: 361: /* sitename(): 362: * Return the site name where the process is running 363: */ 364: char * 365: sitename(pid) 366: pid_t pid; 367: { 368: siteno_t ss; 369: struct sf *st; 370: 371: if ((ss = site(pid)) == -1 || (st = sfnum(ss)) == NULL) 372: return ("unknown"); 373: else 374: return (st->sf_sname); 375: } 376: 377: static int 378: migratepid(pid, new_site) 379: pid_t pid; 380: siteno_t new_site; 381: { 382: struct sf *st; 383: int need_local; 384: 385: need_local = (pid == 0) || (pid == getpid()); 386: 387: if (kill3((pid_t) pid, SIGMIGRATE, new_site) < 0) { 388: xprintf("%d: %s\n", pid, strerror(errno)); 389: return (-1); 390: } 391: 392: if (need_local) { 393: if ((new_site = site(0)) == -1) { 394: xprintf("site: %s\n", strerror(errno)); 395: return (-1); 396: } 397: if ((st = sfnum(new_site)) == NULL) { 398: xprintf("%d: Site not found\n", new_site); 399: return (-1); 400: } 401: if (setlocal(st->sf_local, strlen(st->sf_local)) == -1) { 402: xprintf("setlocal: %s: %s\n", st->sf_local, strerror(errno)); 403: return (-1); 404: } 405: } 406: return (0); 407: } 408: 409: void 410: domigrate(v) 411: Char **v; 412: { 413: struct sf *st; 414: char *s; 415: Char *cp; 416: struct process *pp; 417: int pid, err1 = 0; 418: siteno_t new_site = 0; 419: sigmask_t omask; 420: 421: #ifdef BSDSIGS 422: omask = sigmask(SIGCHLD); 423: if (setintr) 424: omask |= sigmask(SIGINT); 425: omask = sigblock(omask) & ~omask; 426: #else 427: if (setintr) 428: (void) sighold(SIGINT); 429: (void) sighold(SIGCHLD); 430: #endif /* BSDSIGS */ 431: 432: ++v; 433: if (*v[0] == '-') { 434: /* 435: * Do the -site. 436: */ 437: s = short2str(&v[0][1]); 438: if ((st = sfname(s)) == NULL) { 439: setname(s); 440: stderror(ERR_NAME | ERR_STRING, "Site not found"); 441: } 442: new_site = st->sf_id; 443: ++v; 444: } 445: 446: if (!*v || *v[0] == '\0') { 447: if (migratepid(0, new_site) == -1) 448: err1++; 449: } 450: else { 451: gflag = 0, tglob(v); 452: if (gflag) { 453: v = globall(v); 454: if (v == 0) 455: stderror(ERR_NAME | ERR_NOMATCH); 456: } 457: else { 458: v = gargv = saveblk(v); 459: trim(v); 460: } 461: 462: while (v && (cp = *v)) { 463: if (*cp == '%') { 464: pp = pfind(cp); 465: if (kill3((pid_t) - pp->p_jobid, SIGMIGRATE, new_site) < 0) { 466: xprintf("%s: %s\n", short2str(cp), strerror(errno)); 467: err1++; 468: } 469: } 470: else if (!(Isdigit(*cp) || *cp == '-')) 471: stderror(ERR_NAME | ERR_JOBARGS); 472: else { 473: pid = atoi(short2str(cp)); 474: if (migratepid(pid, new_site) == -1) 475: err1++; 476: } 477: v++; 478: } 479: if (gargv) 480: blkfree(gargv), gargv = 0; 481: } 482: 483: done: 484: #ifdef BSDSIGS 485: (void) sigsetmask(omask); 486: #else 487: (void) sigrelse(SIGCHLD); 488: if (setintr) 489: (void) sigrelse(SIGINT); 490: #endif /* BSDSIGS */ 491: if (err1) 492: stderror(ERR_SILENT); 493: } 494: 495: #endif /* TCF */ 496: 497: /*** 498: *** CONVEX Warps. 499: ***/ 500: 501: #ifdef WARP 502: /* 503: * handle the funky warping of symlinks 504: */ 505: #include <warpdb.h> 506: #include <sys/warp.h> 507: 508: static jmp_buf sigsys_buf; 509: 510: static sigret_t 511: catch_sigsys() 512: { 513: longjmp(sigsys_buf, 1); 514: } 515: 516: 517: void 518: dowarp(v) 519: Char **v; 520: { 521: int warp, oldwarp; 522: struct warpent *we; 523: void (*old_sigsys_handler) () = 0; 524: char *newwarp; 525: 526: if (setjmp(sigsys_buf)) { 527: signal(SIGSYS, old_sigsys_handler); 528: stderror(ERR_NAME | ERR_STRING, 529: "You're trapped in a universe you never made"); 530: return; 531: } 532: old_sigsys_handler = signal(SIGSYS, catch_sigsys); 533: 534: warp = getwarp(); 535: 536: v++; 537: if (*v == 0) { /* display warp value */ 538: if (warp < 0) 539: stderror(ERR_NAME | ERR_STRING, "Getwarp failed"); 540: we = getwarpbyvalue(warp); 541: if (we) 542: printf("%s\n", we->w_name); 543: else 544: printf("%d\n", warp); 545: } 546: else { /* set warp value */ 547: oldwarp = warp; 548: newwarp = short2str(*v); 549: if (Isdigit(*v[0])) 550: warp = atoi(newwarp); 551: else { 552: we = getwarpbyname(newwarp); 553: if (we) 554: warp = we->w_value; 555: else 556: warp = -1; 557: } 558: if ((warp < 0) || (warp >= WARP_MAXLINK)) 559: stderror(ERR_NAME | ERR_STRING, "Invalid warp"); 560: if ((setwarp(warp) < 0) || (getwarp() != warp)) { 561: (void) setwarp(oldwarp); 562: stderror(ERR_NAME | ERR_STRING, "Setwarp failed"); 563: } 564: } 565: signal(SIGSYS, old_sigsys_handler); 566: return; 567: } 568: #endif /* WARP */ 569: 570: /*** 571: *** Masscomp 572: ***/ 573: /* Added, DAS DEC-90. */ 574: #ifdef masscomp 575: void 576: douniverse(v) 577: register Char **v; 578: { 579: register Char *cp = v[1]; 580: char ubuf[100]; 581: 582: if (cp == 0) { 583: (void) getuniverse(ubuf); 584: xprintf("%s\n", ubuf); 585: } 586: else if (*cp == '\0' || setuniverse(short2str(cp)) != 0) 587: stderror(ERR_NAME | ERR_STRING, "Illegal universe"); 588: } 589: #endif /* masscomp */ 590: 591: 592: #ifdef _SEQUENT_ 593: /* 594: * Compute the difference in process stats. 595: */ 596: void 597: pr_stat_sub(p2, p1, pr) 598: struct pro_stats *p2, *p1, *pr; 599: { 600: pr->ps_utime.tv_sec = p2->ps_utime.tv_sec - p1->ps_utime.tv_sec; 601: pr->ps_utime.tv_usec = p2->ps_utime.tv_usec - p1->ps_utime.tv_usec; 602: if (pr->ps_utime.tv_usec < 0) { 603: pr->ps_utime.tv_sec -= 1; 604: pr->ps_utime.tv_usec += 1000000; 605: } 606: pr->ps_stime.tv_sec = p2->ps_stime.tv_sec - p1->ps_stime.tv_sec; 607: pr->ps_stime.tv_usec = p2->ps_stime.tv_usec - p1->ps_stime.tv_usec; 608: if (pr->ps_stime.tv_usec < 0) { 609: pr->ps_stime.tv_sec -= 1; 610: pr->ps_stime.tv_usec += 1000000; 611: } 612: 613: pr->ps_maxrss = p2->ps_maxrss - p1->ps_maxrss; 614: pr->ps_pagein = p2->ps_pagein - p1->ps_pagein; 615: pr->ps_reclaim = p2->ps_reclaim - p1->ps_reclaim; 616: pr->ps_zerofill = p2->ps_zerofill - p1->ps_zerofill; 617: pr->ps_pffincr = p2->ps_pffincr - p1->ps_pffincr; 618: pr->ps_pffdecr = p2->ps_pffdecr - p1->ps_pffdecr; 619: pr->ps_swap = p2->ps_swap - p1->ps_swap; 620: pr->ps_syscall = p2->ps_syscall - p1->ps_syscall; 621: pr->ps_volcsw = p2->ps_volcsw - p1->ps_volcsw; 622: pr->ps_involcsw = p2->ps_involcsw - p1->ps_involcsw; 623: pr->ps_signal = p2->ps_signal - p1->ps_signal; 624: pr->ps_lread = p2->ps_lread - p1->ps_lread; 625: pr->ps_lwrite = p2->ps_lwrite - p1->ps_lwrite; 626: pr->ps_bread = p2->ps_bread - p1->ps_bread; 627: pr->ps_bwrite = p2->ps_bwrite - p1->ps_bwrite; 628: pr->ps_phread = p2->ps_phread - p1->ps_phread; 629: pr->ps_phwrite = p2->ps_phwrite - p1->ps_phwrite; 630: } 631: 632: #endif /* _SEQUENT_ */ 633: 634: 635: #ifdef NEEDtcgetpgrp 636: int 637: xtcgetpgrp(fd) 638: int fd; 639: { 640: int pgrp; 641: 642: /* ioctl will handle setting errno correctly. */ 643: if (ioctl(fd, TIOCGPGRP, (ioctl_t) & pgrp) < 0) 644: return (-1); 645: return (pgrp); 646: } 647: 648: #endif /* tcgetpgrp */ 649: 650: 651: #ifdef YPBUGS 652: void 653: fix_yp_bugs() 654: { 655: char *mydomain; 656: 657: /* 658: * PWP: The previous version assumed that yp domain was the same as the 659: * internet name domain. This isn't allways true. (Thanks to Mat Landau 660: * <mlandau@bbn.com> for the original version of this.) 661: */ 662: if (yp_get_default_domain(&mydomain) == 0) { /* if we got a name */ 663: extern void yp_unbind(); 664: 665: yp_unbind(mydomain); 666: } 667: } 668: 669: #endif /* YPBUGS */ 670: 671: 672: void 673: osinit() 674: { 675: extern ptr_t membot; 676: 677: membot = (char *) sbrk(0); 678: 679: #ifdef OREO 680: set42sig(); 681: sigignore(SIGIO); /* ignore SIGIO */ 682: #endif /* OREO */ 683: 684: #ifdef aiws 685: struct sigstack inst; 686: 687: inst.ss_sp = xmalloc(4192) + 4192; 688: inst.ss_onstack = 0; 689: sigstack(&inst, NULL); 690: #endif /* aiws */ 691: 692: #ifdef hpux 693: (void) sigspace(4192); 694: #endif /* hpux */ 695: #ifdef titan 696: end = sbrk(0); 697: #endif /* titan */ 698: 699: #ifdef apollo 700: (void) isapad(); 701: #endif 702: } 703: 704: #ifdef NEEDgethostname 705: #include <sys/utsname.h> 706: 707: int 708: xgethostname(name, namlen) 709: char *name; 710: int namlen; 711: { 712: int i, retval; 713: struct utsname uts; 714: 715: retval = uname(&uts); 716: 717: #ifdef DEBUG 718: xprintf("sysname: %s\n", uts.sysname); 719: xprintf("nodename: %s\n", uts.nodename); 720: xprintf("release: %s\n", uts.release); 721: xprintf("version: %s\n", uts.version); 722: xprintf("machine: %s\n", uts.machine); 723: #endif /* DEBUG */ 724: i = strlen(uts.nodename) + 1; 725: (void) strncpy(name, uts.nodename, i < namlen ? i : namlen); 726: 727: return retval; 728: } /* end gethostname */ 729: 730: #endif /* gethostname */ 731: 732: 733: #ifdef NEEDgetwd 734: static char *strrcpy __P((char *, char *)); 735: 736: /* xgetwd(): 737: * Return the pathname of the current directory, or return 738: * an error message in pathname. 739: */ 740: char * 741: xgetwd(pathname) 742: char *pathname; 743: { 744: DIR *dp; 745: struct dirent *d; 746: 747: struct stat st_root, st_cur, st_next, st_dot; 748: char pathbuf[MAXPATHLEN], next_path_buf[MAXPATHLEN * 2]; 749: char *cur_name_add; 750: char *pathptr, *nextpathptr; 751: 752: /* find the inode of root */ 753: if (stat("/", &st_root) == -1) { 754: (void) xsprintf(pathname, 755: "getwd: Cannot stat \"/\" (%s)", strerror(errno)); 756: return (NULL); 757: } 758: pathbuf[MAXPATHLEN - 1] = '\0'; 759: pathptr = &pathbuf[MAXPATHLEN - 1]; 760: next_path_buf[MAXPATHLEN - 1] = '\0'; 761: cur_name_add = nextpathptr = &next_path_buf[MAXPATHLEN - 1]; 762: 763: /* find the inode of the current directory */ 764: if (lstat("./", &st_cur) == -1) { 765: (void) xsprintf(pathname, 766: "getwd: Cannot stat \".\" (%s)", strerror(errno)); 767: return (NULL); 768: } 769: nextpathptr = strrcpy(nextpathptr, "../"); 770: 771: /* Descend to root */ 772: for (;;) { 773: 774: /* look if we found root yet */ 775: if (st_cur.st_ino == st_root.st_ino && 776: st_cur.st_dev == st_root.st_dev) { 777: if (*pathptr != '/') 778: return ("/"); 779: (void) strcpy(pathname, pathptr); 780: return (pathname); 781: } 782: 783: /* open the parent directory */ 784: if ((dp = opendir(nextpathptr)) == NULL) { 785: (void) xsprintf(pathname, 786: "getwd: Cannot open directory \"%s\" (%s)", 787: nextpathptr, strerror(errno)); 788: return (NULL); 789: } 790: 791: /* look in the parent for the entry with the same inode */ 792: for (d = readdir(dp); d != NULL; d = readdir(dp)) { 793: (void) strcpy(cur_name_add, d->d_name); 794: if (lstat(nextpathptr, &st_next) == -1) { 795: (void) xsprintf(pathname, "getwd: Cannot stat \"%s\" (%s)", 796: d->d_name, strerror(errno)); 797: return (NULL); 798: } 799: if (d->d_name[0] == '.' && d->d_name[1] == '\0') 800: st_dot = st_next; 801: 802: /* check if we found it yet */ 803: if (st_next.st_ino == st_cur.st_ino && 804: st_next.st_dev == st_cur.st_dev) { 805: st_cur = st_dot; 806: pathptr = strrcpy(pathptr, d->d_name); 807: pathptr = strrcpy(pathptr, "/"); 808: nextpathptr = strrcpy(nextpathptr, "../"); 809: *cur_name_add = '\0'; 810: (void) closedir(dp); 811: break; 812: } 813: } 814: if (d == NULL) { 815: (void) xsprintf(pathname, "getwd: Cannot find \".\" in \"..\""); 816: return (NULL); 817: } 818: } 819: } /* end getwd */ 820: 821: /* strrcpy(): 822: * Like strcpy, going backwards and returning the new pointer 823: */ 824: static char * 825: strrcpy(ptr, str) 826: register char *ptr, *str; 827: { 828: register int len = strlen(str); 829: 830: while (len) 831: *--ptr = str[--len]; 832: 833: return (ptr); 834: } /* end strrcpy */ 835: 836: #endif /* getwd */ 837: #ifdef iconuxv 838: #include <sys/vendor.h> 839: #include <sys/b_syscall.h> 840: 841: int 842: vfork() 843: { 844: return sys_local(VEND_ICON_BSD, 66); 845: } 846: 847: #endif /* iconuxv */ 848: 849: #ifdef apollo 850: /*** 851: *** Domain/OS 852: ***/ 853: #undef value /* XXX: Careful here */ 854: #include <apollo/base.h> 855: #include <apollo/loader.h> 856: #include <apollo/error.h> 857: 858: 859: static char * 860: apperr(st) 861: status_$t *st; 862: { 863: static char buf[BUFSIZ]; 864: short e_subl, e_modl, e_codel; 865: error_$string_t e_sub, e_mod, e_code; 866: 867: error_$get_text(*st, e_sub, &e_subl, e_mod, &e_modl, e_code, &e_codel); 868: e_sub[e_subl] = '\0'; 869: e_code[e_codel] = '\0'; 870: e_mod[e_modl] = '\0'; 871: (void) xsprintf(buf, "%s (%s/%s)", e_code, e_sub, e_mod); 872: 873: return(buf); 874: } 875: 876: static int 877: llib(s) 878: Char *s; 879: { 880: short len = Strlen(s); 881: status_$t st; 882: char *t; 883: 884: loader_$inlib(t = short2str(s), len, &st); 885: if (st.all != status_$ok) 886: stderror(ERR_SYSTEM, t, apperr(&st)); 887: } 888: 889: void 890: doinlib(v) 891: Char **v; 892: { 893: setname(short2str(*v++)); 894: gflag = 0, tglob(v); 895: if (gflag) { 896: v = globall(v); 897: if (v == 0) 898: stderror(ERR_NAME | ERR_NOMATCH); 899: } 900: else { 901: v = gargv = saveblk(v); 902: trim(v); 903: } 904: 905: while (v && *v) 906: llib(*v++); 907: if (gargv) 908: blkfree(gargv), gargv = 0; 909: } 910: 911: int 912: getv(v) 913: Char *v; 914: { 915: if (eq(v, STRbsd43)) 916: return(1); 917: else if (eq(v, STRsys53)) 918: return(0); 919: else 920: stderror(ERR_NAME | ERR_SYSTEM, short2str(v), "Invalid system type"); 921: /*NOTREACHED*/ 922: return(0); 923: } 924: 925: void 926: dover(v) 927: Char **v; 928: { 929: Char *p; 930: 931: setname(short2str(*v++)); 932: if (!*v) { 933: if (!(p = Getenv(STRSYSTYPE))) 934: stderror(ERR_NAME | ERR_STRING, "System type is not set"); 935: xprintf("%s\n", short2str(p)); 936: } 937: else { 938: Setenv(STRSYSTYPE, getv(*v) ? STRbsd43 : STRsys53); 939: dohash(); 940: } 941: } 942: 943: /* 944: * Many thanks to rees@citi.umich.edu (Jim Rees) and 945: * mathys@ssdt-tempe.sps.mot.com (Yves Mathys) 946: * For figuring out how to do this... I could have never done 947: * it without their help. 948: */ 949: typedef short enum { 950: name_$wdir_type, 951: name_$ndir_type, 952: name_$node_dir_type, 953: } name_$dir_type_t; 954: 955: void 956: dorootnode(v) 957: Char **v; 958: { 959: name_$dir_type_t dirtype = name_$node_dir_type; 960: uid_$t uid; 961: status_$t st; 962: char *name; 963: short namelen; 964: 965: setname(short2str(*v++)); 966: 967: name = short2str(*v); 968: namelen = strlen(name); 969: 970: name_$resolve(name, &namelen, &uid, &st); 971: if (st.all != status_$ok) 972: stderror(ERR_SYSTEM, name, apperr(&st)); 973: namelen = 0; 974: name_$set_diru(&uid, "", &namelen, &dirtype, &st); 975: if (st.all != status_$ok) 976: stderror(ERR_SYSTEM, name, apperr(&st)); 977: dohash(); 978: } 979: 980: int 981: isapad() 982: { 983: static int res = -1; 984: static status_$t st; 985: 986: if (res == -1) { 987: int strm; 988: if (isatty(0)) 989: strm = 0; 990: if (isatty(1)) 991: strm = 1; 992: if (isatty(2)) 993: strm = 2; 994: else { 995: res = 0; 996: st.all = status_$ok; 997: return(res); 998: } 999: res = stream_$isavt(&strm, &st); 1000: res = res ? 1 : 0; 1001: } 1002: else { 1003: if (st.all != status_$ok) 1004: stderror(ERR_SYSTEM, "stream_$isavt", apperr(&st)); 1005: } 1006: return(res); 1007: } 1008: #endif