1 /* $Header: /src/pub/tcsh/tc.os.c,v 3.52 2000/11/11 23:03:39 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 "sh.h" 38 39 RCSID("$Id: tc.os.c,v 3.52 2000/11/11 23:03:39 christos Exp $") 40 41 #include "tw.h" 42 #include "ed.h" 43 #include "ed.defns.h" /* for the function names */ 44 #include "sh.decls.h" 45 46 #ifdef _UWIN 47 #define TIOCGPGRP TIOCGETPGRP 48 #define TIOCSPGRP TIOCSETPGRP 49 #endif 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 # if EPATH 72 static Char STREPATH[] = {'E', 'P', 'A', 'T', 'H', '\0'}; 73 # endif 74 #endif /* MACH */ 75 static Char *syspaths[] = {STRKPATH, STRCPATH, STRLPATH, STRMPATH, 76 77 #if EPATH 78 STREPATH, 79 #endif 80 0}; 81 #define LOCALSYSPATH "/usr/local" 82 83 /*ARGSUSED*/ 84 void 85 dosetpath(arglist, c) 86 Char **arglist; 87 struct command *c; 88 { 89 extern char *getenv(); 90 sigmask_t omask; 91 Char **pathvars, **cmdargs; 92 char **spaths, **cpaths, **cmds; 93 char *tcp; 94 unsigned int npaths, ncmds; 95 int i, sysflag; 96 97 omask = sigsetmask(sigmask(SIGINT)); 98 99 /* 100 * setpath(3) uses stdio and we want 0, 1, 2 to work... 101 */ 102 if (!didfds) { 103 (void) dcopy(SHIN, 0); 104 (void) dcopy(SHOUT, 1); 105 (void) dcopy(SHDIAG, 2); 106 didfds = 1; 107 } 108 109 for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++); 110 npaths = i - 1; 111 112 cmdargs = &arglist[i]; 113 for (; arglist[i]; i++); 114 ncmds = i - npaths - 1; 115 116 if (npaths) { 117 sysflag = 0; 118 pathvars = &arglist[1]; 119 } 120 else { 121 sysflag = 1; 122 npaths = (sizeof syspaths / sizeof *syspaths) - 1; 123 pathvars = syspaths; 124 } 125 126 /* note that npaths != 0 */ 127 128 spaths = (char **) xmalloc((size_t) npaths * sizeof *spaths); 129 setzero((char *) spaths, npaths * sizeof *spaths); 130 cpaths = (char **) xmalloc((size_t) (npaths + 1) * sizeof *cpaths); 131 setzero((char *) cpaths, (npaths + 1) * sizeof *cpaths); 132 cmds = (char **) xmalloc((size_t) (ncmds + 1) * sizeof *cmds); 133 setzero((char *) cmds, (ncmds + 1) * sizeof *cmds); 134 for (i = 0; i < npaths; i++) { 135 char *val = getenv(short2str(pathvars[i])); 136 137 if (val == NULL) 138 val = ""; 139 140 spaths[i] = (char *) xmalloc((size_t) (Strlen(pathvars[i]) + 141 strlen(val) + 2) * sizeof **spaths); 142 (void) strcpy(spaths[i], short2str(pathvars[i])); 143 (void) strcat(spaths[i], "="); 144 (void) strcat(spaths[i], val); 145 cpaths[i] = spaths[i]; 146 } 147 148 for (i = 0; i < ncmds; i++) { 149 Char *val = globone(cmdargs[i], G_ERROR); 150 151 if (val == NULL) 152 goto abortpath; 153 cmds[i] = (char *) xmalloc((size_t) Strlen(val) + 1); 154 (void) strcpy(cmds[i], short2str(val)); 155 } 156 157 158 if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) { 159 abortpath: 160 if (spaths) { 161 for (i = 0; i < npaths; i++) 162 if (spaths[i]) 163 xfree((ptr_t) spaths[i]); 164 xfree((ptr_t) spaths); 165 } 166 if (cpaths) 167 xfree((ptr_t) cpaths); 168 if (cmds) { 169 for (i = 0; i < ncmds; i++) 170 if (cmds[i]) 171 xfree((ptr_t) cmds[i]); 172 xfree((ptr_t) cmds); 173 } 174 175 (void) sigsetmask(omask); 176 donefds(); 177 return; 178 } 179 180 for (i = 0; i < npaths; i++) { 181 Char *val, *name; 182 183 name = str2short(cpaths[i]); 184 for (val = str2short(cpaths[i]); val && *val && *val != '='; val++); 185 if (val && *val == '=') { 186 *val++ = '\0'; 187 188 tsetenv(name, val); 189 if (Strcmp(name, STRKPATH) == 0) { 190 importpath(val); 191 if (havhash) 192 dohash(NULL, NULL); 193 } 194 *--val = '='; 195 } 196 } 197 (void) sigsetmask(omask); 198 donefds(); 199 } 200 #endif /* MACH */ 201 202 /*** 203 *** AIX 204 ***/ 205 #ifdef TCF 206 /* ARGSUSED */ 207 void 208 dogetxvers(v, c) 209 Char **v; 210 struct command *c; 211 { 212 char xvers[MAXPATHLEN]; 213 214 if (getxvers(xvers, MAXPATHLEN) == -1) 215 stderror(ERR_SYSTEM, "getxvers", strerror(errno)); 216 xprintf("%s\n", xvers); 217 flush(); 218 } 219 220 /*ARGSUSED*/ 221 void 222 dosetxvers(v, c) 223 Char **v; 224 struct command *c; 225 { 226 char *xvers; 227 228 ++v; 229 if (!*v || *v[0] == '\0') 230 xvers = ""; 231 else 232 xvers = short2str(*v); 233 if (setxvers(xvers) == -1) 234 stderror(ERR_SYSTEM, "setxvers", strerror(errno)); 235 } 236 237 #include <sf.h> 238 #ifdef _AIXPS2 239 # define XC_PDP11 0x01 240 # define XC_23 0x02 241 # define XC_Z8K 0x03 242 # define XC_8086 0x04 243 # define XC_68K 0x05 244 # define XC_Z80 0x06 245 # define XC_VAX 0x07 246 # define XC_16032 0x08 247 # define XC_286 0x09 248 # define XC_386 0x0a 249 # define XC_S370 0x0b 250 #else 251 # include <sys/x.out.h> 252 #endif /* _AIXPS2 */ 253 254 static struct xc_cpu_t { 255 short xc_id; 256 char *xc_name; 257 } xcpu[] = 258 { 259 { XC_PDP11, "pdp11" }, 260 { XC_23, "i370" }, 261 { XC_Z8K, "z8000" }, 262 { XC_8086, "i86" }, 263 { XC_68K, "mc68000" }, 264 { XC_Z80, "x80" }, 265 { XC_VAX, "vax" }, 266 { XC_16032, "ns16032" }, 267 { XC_286, "i286" }, 268 { XC_386, "i386" }, 269 { XC_S370, "xa370" }, 270 { 0, NULL } 271 }; 272 273 /* 274 * our local hack table, stolen from x.out.h 275 */ 276 static char * 277 getxcode(xcid) 278 short xcid; 279 { 280 int i; 281 282 for (i = 0; xcpu[i].xc_name != NULL; i++) 283 if (xcpu[i].xc_id == xcid) 284 return (xcpu[i].xc_name); 285 return (NULL); 286 } 287 288 static short 289 getxid(xcname) 290 char *xcname; 291 { 292 int i; 293 294 for (i = 0; xcpu[i].xc_name != NULL; i++) 295 if (strcmp(xcpu[i].xc_name, xcname) == 0) 296 return (xcpu[i].xc_id); 297 return ((short) -1); 298 } 299 300 301 /*ARGSUSED*/ 302 void 303 dogetspath(v, c) 304 Char **v; 305 struct command *c; 306 { 307 int i, j; 308 sitepath_t p[MAXSITE]; 309 struct sf *st; 310 static char *local = "LOCAL "; 311 312 if ((j = getspath(p, MAXSITE)) == -1) 313 stderror(ERR_SYSTEM, "getspath", strerror(errno)); 314 for (i = 0; i < j && (p[i] & SPATH_CPU) != NOSITE; i++) { 315 if (p[i] & SPATH_CPU) { 316 if ((p[i] & SPATH_MASK) == NULLSITE) 317 xprintf(local); 318 else if ((st = sfxcode((short) (p[i] & SPATH_MASK))) != NULL) 319 xprintf("%s ", st->sf_ctype); 320 else { 321 char *xc = getxcode(p[i] & SPATH_MASK); 322 323 if (xc != NULL) 324 xprintf("%s ", xc); 325 else 326 xprintf("*cpu %d* ", (int) (p[i] & SPATH_MASK)); 327 /* 328 * BUG in the aix code... needs that cause if 329 * sfxcode fails once it fails for ever 330 */ 331 endsf(); 332 } 333 } 334 else { 335 if (p[i] == NULLSITE) 336 xprintf(local); 337 else if ((st = sfnum(p[i])) != NULL) 338 xprintf("%s ", st->sf_sname); 339 else 340 xprintf("*site %d* ", (int) (p[i] & SPATH_MASK)); 341 } 342 } 343 xputchar('\n'); 344 flush(); 345 } 346 347 /*ARGSUSED*/ 348 void 349 dosetspath(v, c) 350 Char **v; 351 struct command *c; 352 { 353 int i; 354 short j; 355 char *s; 356 sitepath_t p[MAXSITE]; 357 struct sf *st; 358 359 /* 360 * sfname() on AIX G9.9 at least, mallocs too pointers p, q 361 * then does the equivalent of while (*p++ == *q++) continue; 362 * and then tries to free(p,q) them! Congrats to the wizard who 363 * wrote that one. I bet he tested it really well too. 364 * Sooo, we set dont_free :-) 365 */ 366 dont_free = 1; 367 for (i = 0, v++; *v && *v[0] != '\0'; v++, i++) { 368 s = short2str(*v); 369 if (Isdigit(*s)) 370 p[i] = atoi(s); 371 else if (strcmp(s, "LOCAL") == 0) 372 p[i] = NULLSITE; 373 else if ((st = sfctype(s)) != NULL) 374 p[i] = SPATH_CPU | st->sf_ccode; 375 else if ((j = getxid(s)) != -1) 376 p[i] = SPATH_CPU | j; 377 else if ((st = sfname(s)) != NULL) 378 p[i] = st->sf_id; 379 else { 380 setname(s); 381 stderror(ERR_NAME | ERR_STRING, CGETS(23, 1, "Bad cpu/site name")); 382 } 383 if (i == MAXSITE - 1) 384 stderror(ERR_NAME | ERR_STRING, CGETS(23, 2, "Site path too long")); 385 } 386 if (setspath(p, i) == -1) 387 stderror(ERR_SYSTEM, "setspath", strerror(errno)); 388 dont_free = 0; 389 } 390 391 /* sitename(): 392 * Return the site name where the process is running 393 */ 394 char * 395 sitename(pid) 396 pid_t pid; 397 { 398 siteno_t ss; 399 struct sf *st; 400 401 if ((ss = site(pid)) == -1 || (st = sfnum(ss)) == NULL) 402 return CGETS(23, 3, "unknown"); 403 else 404 return st->sf_sname; 405 } 406 407 static int 408 migratepid(pid, new_site) 409 pid_t pid; 410 siteno_t new_site; 411 { 412 struct sf *st; 413 int need_local; 414 415 need_local = (pid == 0) || (pid == getpid()); 416 417 if (kill3((pid_t) pid, SIGMIGRATE, new_site) < 0) { 418 xprintf("%d: %s\n", pid, strerror(errno)); 419 return (-1); 420 } 421 422 if (need_local) { 423 if ((new_site = site(0)) == -1) { 424 xprintf(CGETS(23, 4, "site: %s\n"), strerror(errno)); 425 return (-1); 426 } 427 if ((st = sfnum(new_site)) == NULL) { 428 xprintf(CGETS(23, 5, "%d: Site not found\n"), new_site); 429 return (-1); 430 } 431 if (setlocal(st->sf_local, strlen(st->sf_local)) == -1) { 432 xprintf(CGETS(23, 6, "setlocal: %s: %s\n"), 433 st->sf_local, strerror(errno)); 434 return (-1); 435 } 436 } 437 return (0); 438 } 439 440 /*ARGSUSED*/ 441 void 442 domigrate(v, c) 443 Char **v; 444 struct command *c; 445 { 446 struct sf *st; 447 char *s; 448 Char *cp; 449 struct process *pp; 450 int err1 = 0; 451 int pid = 0; 452 siteno_t new_site = 0; 453 sigmask_t omask; 454 455 #ifdef BSDSIGS 456 omask = sigmask(SIGCHLD); 457 if (setintr) 458 omask |= sigmask(SIGINT); 459 omask = sigblock(omask) & ~omask; 460 #else 461 if (setintr) 462 (void) sighold(SIGINT); 463 (void) sighold(SIGCHLD); 464 #endif /* BSDSIGS */ 465 466 ++v; 467 if (*v[0] == '-') { 468 /* 469 * Do the -site. 470 */ 471 s = short2str(&v[0][1]); 472 /* 473 * see comment in setspath() 474 */ 475 dont_free = 1; 476 if ((st = sfname(s)) == NULL) { 477 setname(s); 478 stderror(ERR_NAME | ERR_STRING, CGETS(23, 7, "Site not found")); 479 } 480 dont_free = 0; 481 new_site = st->sf_id; 482 ++v; 483 } 484 485 if (!*v || *v[0] == '\0') { 486 if (migratepid(0, new_site) == -1) 487 err1++; 488 } 489 else { 490 gflag = 0, tglob(v); 491 if (gflag) { 492 v = globall(v); 493 if (v == 0) 494 stderror(ERR_NAME | ERR_NOMATCH); 495 } 496 else { 497 v = gargv = saveblk(v); 498 trim(v); 499 } 500 501 while (v && (cp = *v)) { 502 if (*cp == '%') { 503 pp = pfind(cp); 504 if (kill3((pid_t) - pp->p_jobid, SIGMIGRATE, new_site) < 0) { 505 xprintf("%S: %s\n", cp, strerror(errno)); 506 err1++; 507 } 508 } 509 else if (!(Isdigit(*cp) || *cp == '-')) 510 stderror(ERR_NAME | ERR_JOBARGS); 511 else { 512 pid = atoi(short2str(cp)); 513 if (migratepid(pid, new_site) == -1) 514 err1++; 515 } 516 v++; 517 } 518 if (gargv) 519 blkfree(gargv), gargv = 0; 520 } 521 522 done: 523 #ifdef BSDSIGS 524 (void) sigsetmask(omask); 525 #else 526 (void) sigrelse(SIGCHLD); 527 if (setintr) 528 (void) sigrelse(SIGINT); 529 #endif /* BSDSIGS */ 530 if (err1) 531 stderror(ERR_SILENT); 532 } 533 534 #endif /* TCF */ 535 536 /*** 537 *** CRAY ddmode <velo@sesun3.epfl.ch> (Martin Ouwehand EPFL-SIC/SE) 538 ***/ 539 #if defined(_CRAY) && !defined(_CRAYMPP) 540 void 541 dodmmode(v, c) 542 Char **v; 543 struct command *c; 544 { 545 Char *cp = v[1]; 546 547 USE(c); 548 549 if ( !cp ) { 550 int mode; 551 552 mode = dmmode(0); 553 dmmode(mode); 554 xprintf("%d\n",mode); 555 } 556 else { 557 if (cp[1] != '\0') 558 stderror(ERR_NAME | ERR_STRING, 559 CGETS(23, 30, "Too many arguments")); 560 else 561 switch(*cp) { 562 case '0': 563 dmmode(0); 564 break; 565 case '1': 566 dmmode(1); 567 break; 568 default: 569 stderror(ERR_NAME | ERR_STRING, 570 CGETS(23, 31, "Invalid argument")); 571 } 572 } 573 } 574 #endif /* _CRAY && !_CRAYMPP */ 575 576 577 /*** 578 *** CONVEX Warps. 579 ***/ 580 581 #ifdef WARP 582 /* 583 * handle the funky warping of symlinks 584 */ 585 #include <warpdb.h> 586 #include <sys/warp.h> 587 588 static jmp_buf sigsys_buf; 589 590 static sigret_t 591 catch_sigsys() 592 { 593 longjmp(sigsys_buf, 1); 594 } 595 596 597 /*ARGSUSED*/ 598 void 599 dowarp(v, c) 600 Char **v; 601 struct command *c; 602 { 603 int warp, oldwarp; 604 struct warpent *we; 605 void (*old_sigsys_handler) () = 0; 606 char *newwarp; 607 608 if (setjmp(sigsys_buf)) { 609 signal(SIGSYS, old_sigsys_handler); 610 stderror(ERR_NAME | ERR_STRING, 611 CGETS(23, 8, "You're trapped in a universe you never made")); 612 return; 613 } 614 old_sigsys_handler = signal(SIGSYS, catch_sigsys); 615 616 warp = getwarp(); 617 618 v++; 619 if (*v == 0) { /* display warp value */ 620 if (warp < 0) 621 stderror(ERR_NAME | ERR_STRING, CGETS(23, 9, "Getwarp failed")); 622 we = getwarpbyvalue(warp); 623 if (we) 624 printf("%s\n", we->w_name); 625 else 626 printf("%d\n", warp); 627 } 628 else { /* set warp value */ 629 oldwarp = warp; 630 newwarp = short2str(*v); 631 if (Isdigit(*v[0])) 632 warp = atoi(newwarp); 633 else { 634 we = getwarpbyname(newwarp); 635 if (we) 636 warp = we->w_value; 637 else 638 warp = -1; 639 } 640 if ((warp < 0) || (warp >= WARP_MAXLINK)) 641 stderror(ERR_NAME | ERR_STRING, CGETS(23, 10, "Invalid warp")); 642 if ((setwarp(warp) < 0) || (getwarp() != warp)) { 643 (void) setwarp(oldwarp); 644 stderror(ERR_NAME | ERR_STRING, CGETS(23, 11, "Setwarp failed")); 645 } 646 } 647 signal(SIGSYS, old_sigsys_handler); 648 return; 649 } 650 #endif /* WARP */ 651 652 /*** 653 *** Masscomp or HCX 654 ***/ 655 /* Added, DAS DEC-90. */ 656 #if defined(masscomp) || defined(_CX_UX) 657 /*ARGSUSED*/ 658 void 659 douniverse(v, c) 660 register Char **v; 661 struct command *c; 662 { 663 register Char *cp = v[1]; 664 register Char *cp2; /* dunno how many elements v comes in with */ 665 char ubuf[100]; 666 #ifdef BSDSIGS 667 register sigmask_t omask = 0; 668 #endif /* BSDSIGS */ 669 670 if (cp == 0) { 671 (void) getuniverse(ubuf); 672 xprintf("%s\n", ubuf); 673 } 674 else { 675 cp2 = v[2]; 676 if (cp2 == 0) { 677 if (*cp == '\0' || setuniverse(short2str(cp)) != 0) 678 stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe")); 679 } 680 else { 681 (void) getuniverse(ubuf); 682 if (*cp == '\0' || setuniverse(short2str(cp)) != 0) 683 stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe")); 684 if (setintr) 685 #ifdef BSDSIGS 686 omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT); 687 #else /* !BSDSIGS */ 688 (void) sighold(SIGINT); 689 #endif /* BSDSIGS */ 690 lshift(v, 2); 691 if (setintr) 692 #ifdef BSDSIGS 693 (void) sigsetmask(omask); 694 #else /* !BSDSIGS */ 695 (void) sigrelse (SIGINT); 696 #endif /* BSDSIGS */ 697 reexecute(c); 698 (void) setuniverse(ubuf); 699 } 700 } 701 } 702 #endif /* masscomp || _CX_UX */ 703 704 #if defined(_CX_UX) 705 /*ARGSUSED*/ 706 void 707 doatt(v, c) 708 register Char **v; 709 struct command *c; 710 { 711 register Char *cp = v[1]; 712 char ubuf[100]; 713 #ifdef BSDSIGS 714 register sigmask_t omask = 0; 715 #endif /* BSDSIGS */ 716 717 if (cp == 0) 718 (void) setuniverse("att"); 719 else { 720 (void) getuniverse(ubuf); 721 (void) setuniverse("att"); 722 if (setintr) 723 #ifdef BSDSIGS 724 omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT); 725 #else /* !BSDSIGS */ 726 (void) sighold(SIGINT); 727 #endif /* BSDSIGS */ 728 lshift(v, 1); 729 if (setintr) 730 #ifdef BSDSIGS 731 (void) sigsetmask(omask); 732 #else /* !BSDSIGS */ 733 (void) sigrelse (SIGINT); 734 #endif /* BSDSIGS */ 735 reexecute(c); 736 (void) setuniverse(ubuf); 737 } 738 } 739 740 /*ARGSUSED*/ 741 void 742 doucb(v, c) 743 register Char **v; 744 struct command *c; 745 { 746 register Char *cp = v[1]; 747 char ubuf[100]; 748 #ifdef BSDSIGS 749 register sigmask_t omask = 0; 750 #endif /* BSDSIGS */ 751 752 if (cp == 0) 753 (void) setuniverse("ucb"); 754 else { 755 (void) getuniverse(ubuf); 756 (void) setuniverse("ucb"); 757 if (setintr) 758 #ifdef BSDSIGS 759 omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT); 760 #else /* !BSDSIGS */ 761 (void) sighold(SIGINT); 762 #endif /* BSDSIGS */ 763 lshift(v, 1); 764 if (setintr) 765 #ifdef BSDSIGS 766 (void) sigsetmask(omask); 767 #else /* !BSDSIGS */ 768 (void) sigrelse (SIGINT); 769 #endif /* BSDSIGS */ 770 reexecute(c); 771 (void) setuniverse(ubuf); 772 } 773 } 774 #endif /* _CX_UX */ 775 776 #ifdef _SEQUENT_ 777 /* 778 * Compute the difference in process stats. 779 */ 780 void 781 pr_stat_sub(p2, p1, pr) 782 struct process_stats *p2, *p1, *pr; 783 { 784 pr->ps_utime.tv_sec = p2->ps_utime.tv_sec - p1->ps_utime.tv_sec; 785 pr->ps_utime.tv_usec = p2->ps_utime.tv_usec - p1->ps_utime.tv_usec; 786 if (pr->ps_utime.tv_usec < 0) { 787 pr->ps_utime.tv_sec -= 1; 788 pr->ps_utime.tv_usec += 1000000; 789 } 790 pr->ps_stime.tv_sec = p2->ps_stime.tv_sec - p1->ps_stime.tv_sec; 791 pr->ps_stime.tv_usec = p2->ps_stime.tv_usec - p1->ps_stime.tv_usec; 792 if (pr->ps_stime.tv_usec < 0) { 793 pr->ps_stime.tv_sec -= 1; 794 pr->ps_stime.tv_usec += 1000000; 795 } 796 797 pr->ps_maxrss = p2->ps_maxrss - p1->ps_maxrss; 798 pr->ps_pagein = p2->ps_pagein - p1->ps_pagein; 799 pr->ps_reclaim = p2->ps_reclaim - p1->ps_reclaim; 800 pr->ps_zerofill = p2->ps_zerofill - p1->ps_zerofill; 801 pr->ps_pffincr = p2->ps_pffincr - p1->ps_pffincr; 802 pr->ps_pffdecr = p2->ps_pffdecr - p1->ps_pffdecr; 803 pr->ps_swap = p2->ps_swap - p1->ps_swap; 804 pr->ps_syscall = p2->ps_syscall - p1->ps_syscall; 805 pr->ps_volcsw = p2->ps_volcsw - p1->ps_volcsw; 806 pr->ps_involcsw = p2->ps_involcsw - p1->ps_involcsw; 807 pr->ps_signal = p2->ps_signal - p1->ps_signal; 808 pr->ps_lread = p2->ps_lread - p1->ps_lread; 809 pr->ps_lwrite = p2->ps_lwrite - p1->ps_lwrite; 810 pr->ps_bread = p2->ps_bread - p1->ps_bread; 811 pr->ps_bwrite = p2->ps_bwrite - p1->ps_bwrite; 812 pr->ps_phread = p2->ps_phread - p1->ps_phread; 813 pr->ps_phwrite = p2->ps_phwrite - p1->ps_phwrite; 814 } 815 816 #endif /* _SEQUENT_ */ 817 818 819 #ifdef NEEDmemset 820 /* This is a replacement for a missing memset function */ 821 ptr_t xmemset(loc, value, len) 822 ptr_t loc; 823 int len; 824 size_t value; 825 { 826 char *ptr = (char *) loc; 827 828 while (len--) 829 *ptr++ = value; 830 return loc; 831 } 832 #endif /* NEEDmemset */ 833 834 835 #ifdef NEEDmemmove 836 /* memmove(): 837 * This is the ANSI form of bcopy() with the arguments backwards... 838 * Unlike memcpy(), it handles overlaps between source and 839 * destination memory 840 */ 841 ptr_t 842 xmemmove(vdst, vsrc, len) 843 ptr_t vdst; 844 const ptr_t vsrc; 845 size_t len; 846 { 847 const char *src = (const char *) vsrc; 848 char *dst = (char *) vdst; 849 850 if (src == dst) 851 return vdst; 852 853 if (src > dst) { 854 while (len--) 855 *dst++ = *src++; 856 } 857 else { 858 src += len; 859 dst += len; 860 while (len--) 861 *--dst = *--src; 862 } 863 return vdst; 864 } 865 #endif /* NEEDmemmove */ 866 867 868 #ifndef WINNT_NATIVE 869 #ifdef tcgetpgrp 870 int 871 xtcgetpgrp(fd) 872 int fd; 873 { 874 int pgrp; 875 876 /* ioctl will handle setting errno correctly. */ 877 if (ioctl(fd, TIOCGPGRP, (ioctl_t) & pgrp) < 0) 878 return (-1); 879 return (pgrp); 880 } 881 882 /* 883 * XXX: tcsetpgrp is not a macro any more cause on some systems, 884 * pid_t is a short, but the ioctl() takes a pointer to int (pyr) 885 * Thanks to Simon Day (simon@pharaoh.cyborg.bt.co.uk) for pointing 886 * this out. 887 */ 888 int 889 xtcsetpgrp(fd, pgrp) 890 int fd, pgrp; 891 { 892 return ioctl(fd, TIOCSPGRP, (ioctl_t) &pgrp); 893 } 894 895 #endif /* tcgetpgrp */ 896 #endif /* WINNT_NATIVE */ 897 898 899 #ifdef YPBUGS 900 void 901 fix_yp_bugs() 902 { 903 char *mydomain; 904 905 extern int yp_get_default_domain __P((char **)); 906 /* 907 * PWP: The previous version assumed that yp domain was the same as the 908 * internet name domain. This isn't allways true. (Thanks to Mat Landau 909 * <mlandau@bbn.com> for the original version of this.) 910 */ 911 if (yp_get_default_domain(&mydomain) == 0) { /* if we got a name */ 912 extern void yp_unbind __P((const char *)); 913 914 yp_unbind(mydomain); 915 } 916 } 917 918 #endif /* YPBUGS */ 919 920 #ifdef STRCOLLBUG 921 void 922 fix_strcoll_bug() 923 { 924 #if defined(NLS) && !defined(NOSTRCOLL) 925 /* 926 * SunOS4 checks the file descriptor from openlocale() for <= 0 927 * instead of == -1. Someone should tell sun that file descriptor 0 928 * is valid! Our portable hack: open one so we call it with 0 used... 929 * We have to call this routine every time the locale changes... 930 * 931 * Of course it also tries to free the constant locale "C" it initially 932 * had allocated, with the sequence 933 * > setenv LANG "fr" 934 * > ls^D 935 * > unsetenv LANG 936 * But we are smarter than that and just print a warning message. 937 */ 938 int fd = -1; 939 static char *root = "/"; 940 941 if (!didfds) 942 fd = open(root, O_RDONLY); 943 944 (void) strcoll(root, root); 945 946 if (fd != -1) 947 (void) close(fd); 948 #endif 949 } 950 #endif /* STRCOLLBUG */ 951 952 953 #ifdef OREO 954 #include <compat.h> 955 #endif /* OREO */ 956 957 void 958 osinit() 959 { 960 #ifdef OREO 961 set42sig(); 962 setcompat(getcompat() & ~COMPAT_EXEC); 963 sigignore(SIGIO); /* ignore SIGIO */ 964 #endif /* OREO */ 965 966 #ifdef aiws 967 { 968 struct sigstack inst; 969 inst.ss_sp = (char *) xmalloc((size_t) 4192) + 4192; 970 inst.ss_onstack = 0; 971 sigstack(&inst, NULL); 972 } 973 #endif /* aiws */ 974 975 #ifdef apollo 976 (void) isapad(); 977 #endif 978 979 #ifdef _SX 980 /* 981 * kill(SIGCONT) problems, don't know what this syscall does 982 * [schott@rzg.mpg.de] 983 */ 984 syscall(151, getpid(), getpid()); 985 #endif /* _SX */ 986 } 987 988 #ifdef strerror 989 char * 990 xstrerror(i) 991 int i; 992 { 993 static char errbuf[128]; 994 995 if (i >= 0 && i < sys_nerr) { 996 return sys_errlist[i]; 997 } else { 998 (void) xsnprintf(errbuf, sizeof(errbuf), 999 CGETS(23, 13, "Unknown Error: %d"), i); 1000 return errbuf; 1001 } 1002 } 1003 #endif /* strerror */ 1004 1005 #ifdef gethostname 1006 # if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE) 1007 # include <sys/utsname.h> 1008 # endif /* !_MINIX && !__EMX__ && !WINNT_NATIVE */ 1009 1010 int 1011 xgethostname(name, namlen) 1012 char *name; 1013 int namlen; 1014 { 1015 # if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE) 1016 int i, retval; 1017 struct utsname uts; 1018 1019 retval = uname(&uts); 1020 1021 # ifdef DEBUG 1022 xprintf(CGETS(23, 14, "sysname: %s\n"), uts.sysname); 1023 xprintf(CGETS(23, 15, "nodename: %s\n"), uts.nodename); 1024 xprintf(CGETS(23, 16, "release: %s\n"), uts.release); 1025 xprintf(CGETS(23, 17, "version: %s\n"), uts.version); 1026 xprintf(CGETS(23, 18, "machine: %s\n"), uts.machine); 1027 # endif /* DEBUG */ 1028 i = strlen(uts.nodename) + 1; 1029 (void) strncpy(name, uts.nodename, i < namlen ? i : namlen); 1030 1031 return retval; 1032 # else /* !_MINIX && !__EMX__ */ 1033 if (namlen > 0) { 1034 # ifdef __EMX__ 1035 (void) strncpy(name, "OS/2", namlen); 1036 # else /* _MINIX */ 1037 (void) strncpy(name, "minix", namlen); 1038 # endif /* __EMX__ */ 1039 name[namlen-1] = '\0'; 1040 } 1041 return(0); 1042 #endif /* _MINIX && !__EMX__ */ 1043 } /* end xgethostname */ 1044 #endif /* gethostname */ 1045 1046 #ifdef nice 1047 # if defined(_MINIX) && defined(NICE) 1048 # undef _POSIX_SOURCE /* redefined in <lib.h> */ 1049 # undef _MINIX /* redefined in <lib.h> */ 1050 # undef HZ /* redefined in <minix/const.h> */ 1051 # include <lib.h> 1052 # endif /* _MINIX && NICE */ 1053 int 1054 xnice(incr) 1055 int incr; 1056 { 1057 #if defined(_MINIX) && defined(NICE) 1058 return callm1(MM, NICE, incr, 0, 0, NIL_PTR, NIL_PTR, NIL_PTR); 1059 #else 1060 return /* incr ? 0 : */ 0; 1061 #endif /* _MINIX && NICE */ 1062 } /* end xnice */ 1063 #endif /* nice */ 1064 1065 #ifdef NEEDgetcwd 1066 static char *strnrcpy __P((char *, char *, size_t)); 1067 1068 /* xgetcwd(): 1069 * Return the pathname of the current directory, or return 1070 * an error message in pathname. 1071 */ 1072 1073 # ifdef hp9000s500 1074 /* 1075 * From: Bernd Mohr <mohr@faui77.informatik.uni-erlangen.de> 1076 * I also ported the tcsh to the HP9000 Series 500. This computer 1077 * is a little bit different than the other HP 9000 computer. It has 1078 * a HP Chip instead of a Motorola CPU and it is no "real" UNIX. It runs 1079 * HP-UX which is emulated in top of a HP operating system. So, the last 1080 * supported version of HP-UX is 5.2 on the HP9000s500. This has two 1081 * consequences: it supports no job control and it has a filesystem 1082 * without "." and ".." !!! 1083 */ 1084 char * 1085 xgetcwd(pathname, pathlen) 1086 char *pathname; 1087 size_t pathlen; 1088 { 1089 char pathbuf[MAXNAMLEN]; /* temporary pathname buffer */ 1090 char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */ 1091 dev_t rdev; /* root device number */ 1092 DIR *dirp = NULL; /* directory stream */ 1093 ino_t rino; /* root inode number */ 1094 off_t rsize; /* root size */ 1095 struct direct *dir; /* directory entry struct */ 1096 struct stat d, dd; /* file status struct */ 1097 int serrno; 1098 1099 *pnptr = '\0'; 1100 (void) stat("/.", &d); 1101 rdev = d.st_dev; 1102 rino = d.st_ino; 1103 rsize = d.st_size; 1104 for (;;) { 1105 if (stat(".", &d) == -1) { 1106 (void) xsnprintf(pathname, pathlen, CGETS(23, 24, 1107 "getcwd: Cannot stat \".\" (%s)"), strerror(errno)); 1108 goto fail; 1109 } 1110 if (d.st_ino == rino && d.st_dev == rdev && d.st_size == rsize) 1111 break; /* reached root directory */ 1112 if ((dirp = opendir("..")) == NULL) { 1113 (void) xsnprintf(pathname, pathlen, CGETS(23, 19, 1114 "getcwd: Cannot open \"..\" (%s)"), strerror(errno)); 1115 goto fail; 1116 } 1117 if (chdir("..") == -1) { 1118 (void) xsnprintf(pathname, pathlen, CGETS(23, 20, 1119 "getcwd: Cannot chdir to \"..\" (%s)"), strerror(errno)); 1120 goto fail; 1121 } 1122 do { 1123 if ((dir = readdir(dirp)) == NULL) { 1124 (void) xsnprintf(pathname, pathlen, 1125 CGETS(23, 21, "getcwd: Read error in \"..\" (%s)"), 1126 strerror(errno)); 1127 goto fail; 1128 } 1129 if (stat(dir->d_name, &dd) == -1) { 1130 (void) xsnprintf(pathname, pathlen, 1131 CGETS(23, 25, "getcwd: Cannot stat directory \"%s\" (%s)"), 1132 dir->d_name, strerror(errno)); 1133 goto fail; 1134 } 1135 } while (dd.st_ino != d.st_ino || 1136 dd.st_dev != d.st_dev || 1137 dd.st_size != d.st_size); 1138 (void) closedir(dirp); 1139 dirp = NULL; 1140 pnptr = strnrcpy(dirp->d_name, pnptr, pnptr - pathbuf); 1141 pnptr = strnrcpy("/", pnptr, pnptr - pathbuf); 1142 } 1143 1144 if (*pnptr == '\0') /* current dir == root dir */ 1145 (void) strncpy(pathname, "/", pathlen); 1146 else { 1147 (void) strncpy(pathname, pnptr, pathlen); 1148 pathname[pathlen - 1] = '\0'; 1149 if (chdir(pnptr) == -1) { 1150 (void) xsnprintf(pathname, MAXPATHLEN, CGETS(23, 22, 1151 "getcwd: Cannot change back to \".\" (%s)"), 1152 strerror(errno)); 1153 return NULL; 1154 } 1155 } 1156 return pathname; 1157 1158 fail: 1159 serrno = errno; 1160 (void) chdir(strnrcpy(".", pnptr, pnptr - pathbuf)); 1161 errno = serrno; 1162 return NULL; 1163 } 1164 1165 # else /* ! hp9000s500 */ 1166 1167 # if (SYSVREL != 0 && !defined(d_fileno)) || defined(_VMS_POSIX) || defined(WINNT) || defined(_MINIX_VMD) 1168 # define d_fileno d_ino 1169 # endif 1170 1171 char * 1172 xgetcwd(pathname, pathlen) 1173 char *pathname; 1174 size_t pathlen; 1175 { 1176 DIR *dp; 1177 struct dirent *d; 1178 1179 struct stat st_root, st_cur, st_next, st_dotdot; 1180 char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; 1181 char *pathptr, *nextpathptr, *cur_name_add; 1182 int save_errno = 0; 1183 1184 /* find the inode of root */ 1185 if (stat("/", &st_root) == -1) { 1186 (void) xsnprintf(pathname, pathlen, CGETS(23, 23, 1187 "getcwd: Cannot stat \"/\" (%s)"), 1188 strerror(errno)); 1189 return NULL; 1190 } 1191 pathbuf[MAXPATHLEN - 1] = '\0'; 1192 pathptr = &pathbuf[MAXPATHLEN - 1]; 1193 nextpathbuf[MAXPATHLEN - 1] = '\0'; 1194 cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; 1195 1196 /* find the inode of the current directory */ 1197 if (lstat(".", &st_cur) == -1) { 1198 (void) xsnprintf(pathname, pathlen, CGETS(23, 24, 1199 "getcwd: Cannot stat \".\" (%s)"), 1200 strerror(errno)); 1201 return NULL; 1202 } 1203 nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf); 1204 1205 /* Descend to root */ 1206 for (;;) { 1207 1208 /* look if we found root yet */ 1209 if (st_cur.st_ino == st_root.st_ino && 1210 DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { 1211 (void) strncpy(pathname, *pathptr != '/' ? "/" : pathptr, pathlen); 1212 pathname[pathlen - 1] = '\0'; 1213 return pathname; 1214 } 1215 1216 /* open the parent directory */ 1217 if (stat(nextpathptr, &st_dotdot) == -1) { 1218 (void) xsnprintf(pathname, pathlen, CGETS(23, 25, 1219 "getcwd: Cannot stat directory \"%s\" (%s)"), 1220 nextpathptr, strerror(errno)); 1221 return NULL; 1222 } 1223 if ((dp = opendir(nextpathptr)) == NULL) { 1224 (void) xsnprintf(pathname, pathlen, CGETS(23, 26, 1225 "getcwd: Cannot open directory \"%s\" (%s)"), 1226 nextpathptr, strerror(errno)); 1227 return NULL; 1228 } 1229 1230 /* look in the parent for the entry with the same inode */ 1231 if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { 1232 /* Parent has same device. No need to stat every member */ 1233 for (d = readdir(dp); d != NULL; d = readdir(dp)) { 1234 #ifdef __clipper__ 1235 if (((unsigned long)d->d_fileno & 0xffff) == st_cur.st_ino) 1236 break; 1237 #else 1238 if (d->d_fileno == st_cur.st_ino) 1239 break; 1240 #endif 1241 } 1242 } 1243 else { 1244 /* 1245 * Parent has a different device. This is a mount point so we 1246 * need to stat every member 1247 */ 1248 for (d = readdir(dp); d != NULL; d = readdir(dp)) { 1249 if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) 1250 continue; 1251 (void)strncpy(cur_name_add, d->d_name, 1252 (size_t) (&nextpathbuf[sizeof(nextpathbuf) - 1] - cur_name_add)); 1253 if (lstat(nextpathptr, &st_next) == -1) { 1254 /* 1255 * We might not be able to stat() some path components 1256 * if we are using afs, but this is not an error as 1257 * long as we find the one we need; we also save the 1258 * first error to report it if we don't finally succeed. 1259 */ 1260 if (save_errno == 0) 1261 save_errno = errno; 1262 continue; 1263 } 1264 /* check if we found it yet */ 1265 if (st_next.st_ino == st_cur.st_ino && 1266 DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) 1267 break; 1268 } 1269 } 1270 if (d == NULL) { 1271 (void) xsnprintf(pathname, pathlen, CGETS(23, 27, 1272 "getcwd: Cannot find \".\" in \"..\" (%s)"), 1273 strerror(save_errno ? save_errno : ENOENT)); 1274 (void) closedir(dp); 1275 return NULL; 1276 } 1277 else 1278 save_errno = 0; 1279 st_cur = st_dotdot; 1280 pathptr = strnrcpy(pathptr, d->d_name, pathptr - pathbuf); 1281 pathptr = strnrcpy(pathptr, "/", pathptr - pathbuf); 1282 nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf); 1283 *cur_name_add = '\0'; 1284 (void) closedir(dp); 1285 } 1286 } /* end getcwd */ 1287 # endif /* hp9000s500 */ 1288 1289 /* strnrcpy(): 1290 * Like strncpy, going backwards and returning the new pointer 1291 */ 1292 static char * 1293 strnrcpy(ptr, str, siz) 1294 register char *ptr, *str; 1295 size_t siz; 1296 { 1297 register int len = strlen(str); 1298 if (siz == 0) 1299 return ptr; 1300 1301 while (len && siz--) 1302 *--ptr = str[--len]; 1303 1304 return (ptr); 1305 } /* end strnrcpy */ 1306 #endif /* getcwd */ 1307 1308 #ifdef apollo 1309 /*** 1310 *** Domain/OS 1311 ***/ 1312 #include <apollo/base.h> 1313 #include <apollo/loader.h> 1314 #include <apollo/error.h> 1315 1316 1317 static char * 1318 apperr(st) 1319 status_$t *st; 1320 { 1321 static char buf[BUFSIZE]; 1322 short e_subl, e_modl, e_codel; 1323 error_$string_t e_sub, e_mod, e_code; 1324 1325 error_$get_text(*st, e_sub, &e_subl, e_mod, &e_modl, e_code, &e_codel); 1326 e_sub[e_subl] = '\0'; 1327 e_code[e_codel] = '\0'; 1328 e_mod[e_modl] = '\0'; 1329 (void) xsnprintf(buf, sizeof(buf), "%s (%s/%s)", e_code, e_sub, e_mod); 1330 1331 return(buf); 1332 } 1333 1334 static int 1335 llib(s) 1336 Char *s; 1337 { 1338 short len = Strlen(s); 1339 status_$t st; 1340 char *t; 1341 1342 loader_$inlib(t = short2str(s), len, &st); 1343 if (st.all != status_$ok) 1344 stderror(ERR_SYSTEM, t, apperr(&st)); 1345 } 1346 1347 /*ARGSUSED*/ 1348 void 1349 doinlib(v, c) 1350 Char **v; 1351 struct command *c; 1352 { 1353 setname(short2str(*v++)); 1354 gflag = 0, tglob(v); 1355 if (gflag) { 1356 v = globall(v); 1357 if (v == 0) 1358 stderror(ERR_NAME | ERR_NOMATCH); 1359 } 1360 else { 1361 v = gargv = saveblk(v); 1362 trim(v); 1363 } 1364 1365 while (v && *v) 1366 llib(*v++); 1367 if (gargv) 1368 blkfree(gargv), gargv = 0; 1369 } 1370 1371 int 1372 getv(v) 1373 Char *v; 1374 { 1375 if (eq(v, STRbsd43)) 1376 return(1); 1377 else if (eq(v, STRsys53)) 1378 return(0); 1379 else 1380 stderror(ERR_NAME | ERR_SYSTEM, short2str(v), 1381 CGETS(23, 28, "Invalid system type")); 1382 /*NOTREACHED*/ 1383 return(0); 1384 } 1385 1386 /*ARGSUSED*/ 1387 void 1388 dover(v, c) 1389 Char **v; 1390 struct command *c; 1391 { 1392 Char *p; 1393 1394 setname(short2str(*v++)); 1395 if (!*v) { 1396 if (!(p = tgetenv(STRSYSTYPE))) 1397 stderror(ERR_NAME | ERR_STRING, 1398 CGETS(23, 29, "System type is not set")); 1399 xprintf("%S\n", p); 1400 } 1401 else { 1402 tsetenv(STRSYSTYPE, getv(*v) ? STRbsd43 : STRsys53); 1403 dohash(NULL, NULL); 1404 } 1405 } 1406 1407 /* 1408 * Many thanks to rees@citi.umich.edu (Jim Rees) and 1409 * mathys@ssdt-tempe.sps.mot.com (Yves Mathys) 1410 * For figuring out how to do this... I could have never done 1411 * it without their help. 1412 */ 1413 typedef short enum { 1414 name_$wdir_type, 1415 name_$ndir_type, 1416 name_$node_dir_type, 1417 } name_$dir_type_t; 1418 1419 /*ARGSUSED*/ 1420 void 1421 dorootnode(v, c) 1422 Char **v; 1423 struct command *c; 1424 { 1425 name_$dir_type_t dirtype = name_$node_dir_type; 1426 uid_$t uid; 1427 status_$t st; 1428 char *name; 1429 short namelen; 1430 1431 setname(short2str(*v++)); 1432 1433 name = short2str(*v); 1434 namelen = strlen(name); 1435 1436 name_$resolve(name, &namelen, &uid, &st); 1437 if (st.all != status_$ok) 1438 stderror(ERR_SYSTEM, name, apperr(&st)); 1439 namelen = 0; 1440 name_$set_diru(&uid, "", &namelen, &dirtype, &st); 1441 if (st.all != status_$ok) 1442 stderror(ERR_SYSTEM, name, apperr(&st)); 1443 dohash(NULL, NULL); 1444 } 1445 1446 int 1447 isapad() 1448 { 1449 static int res = -1; 1450 static status_$t st; 1451 1452 if (res == -1) { 1453 int strm; 1454 if (isatty(0)) 1455 strm = 0; 1456 if (isatty(1)) 1457 strm = 1; 1458 if (isatty(2)) 1459 strm = 2; 1460 else { 1461 res = 0; 1462 st.all = status_$ok; 1463 return(res); 1464 } 1465 res = stream_$isavt(&strm, &st); 1466 res = res ? 1 : 0; 1467 } 1468 else { 1469 if (st.all != status_$ok) 1470 stderror(ERR_SYSTEM, "stream_$isavt", apperr(&st)); 1471 } 1472 return(res); 1473 } 1474 #endif 1475