1232633Smp/* $Header: /p/tcsh/cvsroot/tcsh/tc.os.c,v 3.72 2011/01/25 13:58:19 christos Exp $ */ 259243Sobrien/* 359243Sobrien * tc.os.c: OS Dependent builtin functions 459243Sobrien */ 559243Sobrien/*- 659243Sobrien * Copyright (c) 1980, 1991 The Regents of the University of California. 759243Sobrien * All rights reserved. 859243Sobrien * 959243Sobrien * Redistribution and use in source and binary forms, with or without 1059243Sobrien * modification, are permitted provided that the following conditions 1159243Sobrien * are met: 1259243Sobrien * 1. Redistributions of source code must retain the above copyright 1359243Sobrien * notice, this list of conditions and the following disclaimer. 1459243Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1559243Sobrien * notice, this list of conditions and the following disclaimer in the 1659243Sobrien * documentation and/or other materials provided with the distribution. 17100616Smp * 3. Neither the name of the University nor the names of its contributors 1859243Sobrien * may be used to endorse or promote products derived from this software 1959243Sobrien * without specific prior written permission. 2059243Sobrien * 2159243Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2259243Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2359243Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2459243Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2559243Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2659243Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2759243Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2859243Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2959243Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3059243Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3159243Sobrien * SUCH DAMAGE. 3259243Sobrien */ 3359243Sobrien#include "sh.h" 3459243Sobrien 35232633SmpRCSID("$tcsh: tc.os.c,v 3.72 2011/01/25 13:58:19 christos Exp $") 3659243Sobrien 3759243Sobrien#include "tw.h" 3859243Sobrien#include "ed.h" 3959243Sobrien#include "ed.defns.h" /* for the function names */ 4059243Sobrien#include "sh.decls.h" 4159243Sobrien 4259243Sobrien#ifdef _UWIN 4359243Sobrien#define TIOCGPGRP TIOCGETPGRP 4459243Sobrien#define TIOCSPGRP TIOCSETPGRP 4559243Sobrien#endif 4659243Sobrien 4759243Sobrien/*** 4859243Sobrien *** MACH 4959243Sobrien ***/ 5059243Sobrien 5159243Sobrien#ifdef MACH 5259243Sobrien/* dosetpath -- setpath built-in command 5359243Sobrien * 5459243Sobrien ********************************************************************** 5559243Sobrien * HISTORY 5659243Sobrien * 08-May-88 Richard Draves (rpd) at Carnegie-Mellon University 5759243Sobrien * Major changes to remove artificial limits on sizes and numbers 5859243Sobrien * of paths. 5959243Sobrien * 6059243Sobrien ********************************************************************** 6159243Sobrien */ 6259243Sobrien 6359243Sobrien#ifdef MACH 6459243Sobrienstatic Char STRCPATH[] = {'C', 'P', 'A', 'T', 'H', '\0'}; 6559243Sobrienstatic Char STRLPATH[] = {'L', 'P', 'A', 'T', 'H', '\0'}; 6659243Sobrienstatic Char STRMPATH[] = {'M', 'P', 'A', 'T', 'H', '\0'}; 6759243Sobrien# if EPATH 6859243Sobrienstatic Char STREPATH[] = {'E', 'P', 'A', 'T', 'H', '\0'}; 6959243Sobrien# endif 7059243Sobrien#endif /* MACH */ 7159243Sobrienstatic Char *syspaths[] = {STRKPATH, STRCPATH, STRLPATH, STRMPATH, 7259243Sobrien 7359243Sobrien#if EPATH 7459243Sobrien STREPATH, 7559243Sobrien#endif 7659243Sobrien 0}; 7759243Sobrien#define LOCALSYSPATH "/usr/local" 7859243Sobrien 7959243Sobrien/*ARGSUSED*/ 8059243Sobrienvoid 81167465Smpdosetpath(Char **arglist, struct command *c) 8259243Sobrien{ 8359243Sobrien extern char *getenv(); 8459243Sobrien Char **pathvars, **cmdargs; 8559243Sobrien char **spaths, **cpaths, **cmds; 8659243Sobrien char *tcp; 8759243Sobrien unsigned int npaths, ncmds; 8859243Sobrien int i, sysflag; 8959243Sobrien 90167465Smp pintr_disabled++; 91167465Smp cleanup_push(&pintr_disabled, disabled_cleanup); 9259243Sobrien 9359243Sobrien /* 9459243Sobrien * setpath(3) uses stdio and we want 0, 1, 2 to work... 9559243Sobrien */ 9659243Sobrien if (!didfds) { 9759243Sobrien (void) dcopy(SHIN, 0); 9859243Sobrien (void) dcopy(SHOUT, 1); 9959243Sobrien (void) dcopy(SHDIAG, 2); 10059243Sobrien didfds = 1; 10159243Sobrien } 10259243Sobrien 10359243Sobrien for (i = 1; arglist[i] && (arglist[i][0] != '-'); i++); 10459243Sobrien npaths = i - 1; 10559243Sobrien 10659243Sobrien cmdargs = &arglist[i]; 10759243Sobrien for (; arglist[i]; i++); 10859243Sobrien ncmds = i - npaths - 1; 10959243Sobrien 11059243Sobrien if (npaths) { 11159243Sobrien sysflag = 0; 11259243Sobrien pathvars = &arglist[1]; 11359243Sobrien } 11459243Sobrien else { 11559243Sobrien sysflag = 1; 11659243Sobrien npaths = (sizeof syspaths / sizeof *syspaths) - 1; 11759243Sobrien pathvars = syspaths; 11859243Sobrien } 11959243Sobrien 12059243Sobrien /* note that npaths != 0 */ 12159243Sobrien 122167465Smp spaths = xmalloc(npaths * sizeof *spaths); 123167465Smp setzero(spaths, npaths * sizeof *spaths); 124167465Smp cpaths = xmalloc((npaths + 1) * sizeof *cpaths); 125167465Smp setzero(cpaths, (npaths + 1) * sizeof *cpaths); 126167465Smp cmds = xmalloc((ncmds + 1) * sizeof *cmds); 127167465Smp setzero(cmds, (ncmds + 1) * sizeof *cmds); 12859243Sobrien for (i = 0; i < npaths; i++) { 12959243Sobrien char *val = getenv(short2str(pathvars[i])); 13059243Sobrien 13159243Sobrien if (val == NULL) 13259243Sobrien val = ""; 13359243Sobrien 134167465Smp spaths[i] = xmalloc((Strlen(pathvars[i]) + strlen(val) + 2) * 135167465Smp sizeof **spaths); 13659243Sobrien (void) strcpy(spaths[i], short2str(pathvars[i])); 13759243Sobrien (void) strcat(spaths[i], "="); 13859243Sobrien (void) strcat(spaths[i], val); 13959243Sobrien cpaths[i] = spaths[i]; 14059243Sobrien } 14159243Sobrien 14259243Sobrien for (i = 0; i < ncmds; i++) { 143167465Smp Char *val = globone(cmdargs[i], G_ERROR);/*FIXRESET*/ 14459243Sobrien 14559243Sobrien if (val == NULL) 14659243Sobrien goto abortpath; 147167465Smp cmds[i] = strsave(short2str(val)); 14859243Sobrien } 14959243Sobrien 15059243Sobrien 15159243Sobrien if (setpath(cpaths, cmds, LOCALSYSPATH, sysflag, 1) < 0) { 15259243Sobrienabortpath: 15359243Sobrien if (spaths) { 15459243Sobrien for (i = 0; i < npaths; i++) 155167465Smp xfree(spaths[i]); 156167465Smp xfree(spaths); 15759243Sobrien } 158167465Smp xfree(cpaths); 15959243Sobrien if (cmds) { 16059243Sobrien for (i = 0; i < ncmds; i++) 161167465Smp xfree(cmds[i]); 162167465Smp xfree(cmds); 16359243Sobrien } 16459243Sobrien 165167465Smp cleanup_until(&pintr_disabled); 16659243Sobrien donefds(); 16759243Sobrien return; 16859243Sobrien } 16959243Sobrien 17059243Sobrien for (i = 0; i < npaths; i++) { 17159243Sobrien Char *val, *name; 17259243Sobrien 17359243Sobrien name = str2short(cpaths[i]); 17459243Sobrien for (val = str2short(cpaths[i]); val && *val && *val != '='; val++); 17559243Sobrien if (val && *val == '=') { 17659243Sobrien *val++ = '\0'; 17759243Sobrien 178167465Smp tsetenv(name, val);/*FIXRESET*/ 17959243Sobrien if (Strcmp(name, STRKPATH) == 0) { 180167465Smp importpath(val);/*FIXRESET*/ 18159243Sobrien if (havhash) 182167465Smp dohash(NULL, NULL);/*FIXRESET*/ 18359243Sobrien } 18459243Sobrien *--val = '='; 18559243Sobrien } 18659243Sobrien } 187167465Smp cleanup_until(&pintr_disabled); 18859243Sobrien donefds(); 18959243Sobrien} 19059243Sobrien#endif /* MACH */ 19159243Sobrien 19259243Sobrien/*** 19359243Sobrien *** AIX 19459243Sobrien ***/ 19559243Sobrien#ifdef TCF 19659243Sobrien/* ARGSUSED */ 19759243Sobrienvoid 198167465Smpdogetxvers(Char **v, struct command *c) 19959243Sobrien{ 20059243Sobrien char xvers[MAXPATHLEN]; 20159243Sobrien 20259243Sobrien if (getxvers(xvers, MAXPATHLEN) == -1) 20359243Sobrien stderror(ERR_SYSTEM, "getxvers", strerror(errno)); 20459243Sobrien xprintf("%s\n", xvers); 20559243Sobrien flush(); 20659243Sobrien} 20759243Sobrien 20859243Sobrien/*ARGSUSED*/ 20959243Sobrienvoid 210167465Smpdosetxvers(Char **v, struct command *c) 21159243Sobrien{ 21259243Sobrien char *xvers; 21359243Sobrien 21459243Sobrien ++v; 21559243Sobrien if (!*v || *v[0] == '\0') 21659243Sobrien xvers = ""; 21759243Sobrien else 21859243Sobrien xvers = short2str(*v); 21959243Sobrien if (setxvers(xvers) == -1) 22059243Sobrien stderror(ERR_SYSTEM, "setxvers", strerror(errno)); 22159243Sobrien} 22259243Sobrien 22359243Sobrien#include <sf.h> 22459243Sobrien#ifdef _AIXPS2 22559243Sobrien# define XC_PDP11 0x01 22659243Sobrien# define XC_23 0x02 22759243Sobrien# define XC_Z8K 0x03 22859243Sobrien# define XC_8086 0x04 22959243Sobrien# define XC_68K 0x05 23059243Sobrien# define XC_Z80 0x06 23159243Sobrien# define XC_VAX 0x07 23259243Sobrien# define XC_16032 0x08 23359243Sobrien# define XC_286 0x09 23459243Sobrien# define XC_386 0x0a 23559243Sobrien# define XC_S370 0x0b 23659243Sobrien#else 23759243Sobrien# include <sys/x.out.h> 23859243Sobrien#endif /* _AIXPS2 */ 23959243Sobrien 24059243Sobrienstatic struct xc_cpu_t { 24159243Sobrien short xc_id; 24259243Sobrien char *xc_name; 24359243Sobrien} xcpu[] = 24459243Sobrien{ 24559243Sobrien { XC_PDP11, "pdp11" }, 24659243Sobrien { XC_23, "i370" }, 24759243Sobrien { XC_Z8K, "z8000" }, 24859243Sobrien { XC_8086, "i86" }, 24959243Sobrien { XC_68K, "mc68000" }, 25059243Sobrien { XC_Z80, "x80" }, 25159243Sobrien { XC_VAX, "vax" }, 25259243Sobrien { XC_16032, "ns16032" }, 25359243Sobrien { XC_286, "i286" }, 25459243Sobrien { XC_386, "i386" }, 25559243Sobrien { XC_S370, "xa370" }, 25659243Sobrien { 0, NULL } 25759243Sobrien}; 25859243Sobrien 25959243Sobrien/* 26059243Sobrien * our local hack table, stolen from x.out.h 26159243Sobrien */ 26259243Sobrienstatic char * 263167465Smpgetxcode(short xcid) 26459243Sobrien{ 26559243Sobrien int i; 26659243Sobrien 26759243Sobrien for (i = 0; xcpu[i].xc_name != NULL; i++) 26859243Sobrien if (xcpu[i].xc_id == xcid) 26959243Sobrien return (xcpu[i].xc_name); 27059243Sobrien return (NULL); 27159243Sobrien} 27259243Sobrien 27359243Sobrienstatic short 274167465Smpgetxid(char *xcname) 27559243Sobrien{ 27659243Sobrien int i; 27759243Sobrien 27859243Sobrien for (i = 0; xcpu[i].xc_name != NULL; i++) 27959243Sobrien if (strcmp(xcpu[i].xc_name, xcname) == 0) 28059243Sobrien return (xcpu[i].xc_id); 28159243Sobrien return ((short) -1); 28259243Sobrien} 28359243Sobrien 28459243Sobrien 28559243Sobrien/*ARGSUSED*/ 28659243Sobrienvoid 287167465Smpdogetspath(Char **v, struct command *c) 28859243Sobrien{ 28959243Sobrien int i, j; 29059243Sobrien sitepath_t p[MAXSITE]; 29159243Sobrien struct sf *st; 29259243Sobrien static char *local = "LOCAL "; 29359243Sobrien 29459243Sobrien if ((j = getspath(p, MAXSITE)) == -1) 29559243Sobrien stderror(ERR_SYSTEM, "getspath", strerror(errno)); 29659243Sobrien for (i = 0; i < j && (p[i] & SPATH_CPU) != NOSITE; i++) { 29759243Sobrien if (p[i] & SPATH_CPU) { 29859243Sobrien if ((p[i] & SPATH_MASK) == NULLSITE) 29959243Sobrien xprintf(local); 30059243Sobrien else if ((st = sfxcode((short) (p[i] & SPATH_MASK))) != NULL) 30159243Sobrien xprintf("%s ", st->sf_ctype); 30259243Sobrien else { 30359243Sobrien char *xc = getxcode(p[i] & SPATH_MASK); 30459243Sobrien 30559243Sobrien if (xc != NULL) 30659243Sobrien xprintf("%s ", xc); 30759243Sobrien else 30859243Sobrien xprintf("*cpu %d* ", (int) (p[i] & SPATH_MASK)); 30959243Sobrien /* 31059243Sobrien * BUG in the aix code... needs that cause if 31159243Sobrien * sfxcode fails once it fails for ever 31259243Sobrien */ 31359243Sobrien endsf(); 31459243Sobrien } 31559243Sobrien } 31659243Sobrien else { 31759243Sobrien if (p[i] == NULLSITE) 31859243Sobrien xprintf(local); 31959243Sobrien else if ((st = sfnum(p[i])) != NULL) 32059243Sobrien xprintf("%s ", st->sf_sname); 32159243Sobrien else 32259243Sobrien xprintf("*site %d* ", (int) (p[i] & SPATH_MASK)); 32359243Sobrien } 32459243Sobrien } 32559243Sobrien xputchar('\n'); 32659243Sobrien flush(); 32759243Sobrien} 32859243Sobrien 32959243Sobrien/*ARGSUSED*/ 33059243Sobrienvoid 331167465Smpdosetspath(Char **v, struct command *c) 33259243Sobrien{ 33359243Sobrien int i; 33459243Sobrien short j; 33559243Sobrien char *s; 33659243Sobrien sitepath_t p[MAXSITE]; 33759243Sobrien struct sf *st; 33859243Sobrien 33959243Sobrien /* 34059243Sobrien * sfname() on AIX G9.9 at least, mallocs too pointers p, q 34159243Sobrien * then does the equivalent of while (*p++ == *q++) continue; 34259243Sobrien * and then tries to free(p,q) them! Congrats to the wizard who 34359243Sobrien * wrote that one. I bet he tested it really well too. 34459243Sobrien * Sooo, we set dont_free :-) 34559243Sobrien */ 34659243Sobrien dont_free = 1; 34759243Sobrien for (i = 0, v++; *v && *v[0] != '\0'; v++, i++) { 34859243Sobrien s = short2str(*v); 349145479Smp if (isdigit(*s)) 35059243Sobrien p[i] = atoi(s); 35159243Sobrien else if (strcmp(s, "LOCAL") == 0) 35259243Sobrien p[i] = NULLSITE; 35359243Sobrien else if ((st = sfctype(s)) != NULL) 35459243Sobrien p[i] = SPATH_CPU | st->sf_ccode; 35559243Sobrien else if ((j = getxid(s)) != -1) 35659243Sobrien p[i] = SPATH_CPU | j; 35759243Sobrien else if ((st = sfname(s)) != NULL) 35859243Sobrien p[i] = st->sf_id; 35959243Sobrien else { 36059243Sobrien setname(s); 36159243Sobrien stderror(ERR_NAME | ERR_STRING, CGETS(23, 1, "Bad cpu/site name")); 36259243Sobrien } 36359243Sobrien if (i == MAXSITE - 1) 36459243Sobrien stderror(ERR_NAME | ERR_STRING, CGETS(23, 2, "Site path too long")); 36559243Sobrien } 36659243Sobrien if (setspath(p, i) == -1) 36759243Sobrien stderror(ERR_SYSTEM, "setspath", strerror(errno)); 36859243Sobrien dont_free = 0; 36959243Sobrien} 37059243Sobrien 37159243Sobrien/* sitename(): 37259243Sobrien * Return the site name where the process is running 37359243Sobrien */ 37459243Sobrienchar * 375167465Smpsitename(pid_t pid) 37659243Sobrien{ 37759243Sobrien siteno_t ss; 37859243Sobrien struct sf *st; 37959243Sobrien 38059243Sobrien if ((ss = site(pid)) == -1 || (st = sfnum(ss)) == NULL) 38159243Sobrien return CGETS(23, 3, "unknown"); 38259243Sobrien else 38359243Sobrien return st->sf_sname; 38459243Sobrien} 38559243Sobrien 38659243Sobrienstatic int 387167465Smpmigratepid(pit_t pid, siteno_t new_site) 38859243Sobrien{ 38959243Sobrien struct sf *st; 39059243Sobrien int need_local; 39159243Sobrien 39259243Sobrien need_local = (pid == 0) || (pid == getpid()); 39359243Sobrien 394167465Smp if (kill3(pid, SIGMIGRATE, new_site) < 0) { 39559243Sobrien xprintf("%d: %s\n", pid, strerror(errno)); 39659243Sobrien return (-1); 39759243Sobrien } 39859243Sobrien 39959243Sobrien if (need_local) { 40059243Sobrien if ((new_site = site(0)) == -1) { 40159243Sobrien xprintf(CGETS(23, 4, "site: %s\n"), strerror(errno)); 40259243Sobrien return (-1); 40359243Sobrien } 40459243Sobrien if ((st = sfnum(new_site)) == NULL) { 40559243Sobrien xprintf(CGETS(23, 5, "%d: Site not found\n"), new_site); 40659243Sobrien return (-1); 40759243Sobrien } 40859243Sobrien if (setlocal(st->sf_local, strlen(st->sf_local)) == -1) { 40959243Sobrien xprintf(CGETS(23, 6, "setlocal: %s: %s\n"), 41059243Sobrien st->sf_local, strerror(errno)); 41159243Sobrien return (-1); 41259243Sobrien } 41359243Sobrien } 41459243Sobrien return (0); 41559243Sobrien} 41659243Sobrien 41759243Sobrien/*ARGSUSED*/ 41859243Sobrienvoid 419167465Smpdomigrate(Char **v, struct command *c) 42059243Sobrien{ 42159243Sobrien struct sf *st; 42259243Sobrien char *s; 42359243Sobrien Char *cp; 42459243Sobrien struct process *pp; 42559243Sobrien int err1 = 0; 42659243Sobrien int pid = 0; 42759243Sobrien siteno_t new_site = 0; 42859243Sobrien 429167465Smp pchild_disabled++; 430167465Smp cleanup_push(&pchild_disabled, disabled_cleanup); 431167465Smp if (setintr) { 432167465Smp pintr_disabled++; 433167465Smp cleanup_push(&pintr_disabled, disabled_cleanup); 434167465Smp } 43559243Sobrien 43659243Sobrien ++v; 43759243Sobrien if (*v[0] == '-') { 43859243Sobrien /* 43959243Sobrien * Do the -site. 44059243Sobrien */ 44159243Sobrien s = short2str(&v[0][1]); 44259243Sobrien /* 44359243Sobrien * see comment in setspath() 44459243Sobrien */ 44559243Sobrien dont_free = 1; 44659243Sobrien if ((st = sfname(s)) == NULL) { 447167465Smp dont_free = 0; 44859243Sobrien setname(s); 44959243Sobrien stderror(ERR_NAME | ERR_STRING, CGETS(23, 7, "Site not found")); 45059243Sobrien } 45159243Sobrien dont_free = 0; 45259243Sobrien new_site = st->sf_id; 45359243Sobrien ++v; 45459243Sobrien } 45559243Sobrien 45659243Sobrien if (!*v || *v[0] == '\0') { 45759243Sobrien if (migratepid(0, new_site) == -1) 45859243Sobrien err1++; 45959243Sobrien } 46059243Sobrien else { 461167465Smp Char **globbed; 46259243Sobrien 463167465Smp v = glob_all_or_error(v); 464167465Smp globbed = v; 465167465Smp cleanup_push(globbed, blk_cleanup); 466167465Smp 46759243Sobrien while (v && (cp = *v)) { 46859243Sobrien if (*cp == '%') { 46959243Sobrien pp = pfind(cp); 470167465Smp if (kill3(- pp->p_jobid, SIGMIGRATE, new_site) < 0) { 47159243Sobrien xprintf("%S: %s\n", cp, strerror(errno)); 47259243Sobrien err1++; 47359243Sobrien } 47459243Sobrien } 47559243Sobrien else if (!(Isdigit(*cp) || *cp == '-')) 47659243Sobrien stderror(ERR_NAME | ERR_JOBARGS); 47759243Sobrien else { 47859243Sobrien pid = atoi(short2str(cp)); 47959243Sobrien if (migratepid(pid, new_site) == -1) 48059243Sobrien err1++; 48159243Sobrien } 48259243Sobrien v++; 48359243Sobrien } 484167465Smp cleanup_until(globbed); 48559243Sobrien } 48659243Sobrien 48759243Sobriendone: 488167465Smp cleanup_until(&pchild_disabled); 48959243Sobrien if (err1) 49059243Sobrien stderror(ERR_SILENT); 49159243Sobrien} 49259243Sobrien 49359243Sobrien#endif /* TCF */ 49459243Sobrien 49559243Sobrien/*** 49659243Sobrien *** CRAY ddmode <velo@sesun3.epfl.ch> (Martin Ouwehand EPFL-SIC/SE) 49759243Sobrien ***/ 49859243Sobrien#if defined(_CRAY) && !defined(_CRAYMPP) 49959243Sobrienvoid 500167465Smpdodmmode(Char **v, struct command *c) 50159243Sobrien{ 50259243Sobrien Char *cp = v[1]; 50359243Sobrien 50459243Sobrien USE(c); 50559243Sobrien 50659243Sobrien if ( !cp ) { 50759243Sobrien int mode; 50859243Sobrien 50959243Sobrien mode = dmmode(0); 51059243Sobrien dmmode(mode); 51159243Sobrien xprintf("%d\n",mode); 51259243Sobrien } 51359243Sobrien else { 51459243Sobrien if (cp[1] != '\0') 515167465Smp stderror(ERR_NAME | ERR_STRING, 51659243Sobrien CGETS(23, 30, "Too many arguments")); 51759243Sobrien else 51859243Sobrien switch(*cp) { 51959243Sobrien case '0': 52059243Sobrien dmmode(0); 52159243Sobrien break; 52259243Sobrien case '1': 52359243Sobrien dmmode(1); 52459243Sobrien break; 52559243Sobrien default: 526167465Smp stderror(ERR_NAME | ERR_STRING, 52759243Sobrien CGETS(23, 31, "Invalid argument")); 52859243Sobrien } 52959243Sobrien } 53059243Sobrien} 53159243Sobrien#endif /* _CRAY && !_CRAYMPP */ 53259243Sobrien 53359243Sobrien 53459243Sobrien/*** 53559243Sobrien *** CONVEX Warps. 53659243Sobrien ***/ 53759243Sobrien 53859243Sobrien#ifdef WARP 53959243Sobrien/* 54059243Sobrien * handle the funky warping of symlinks 54159243Sobrien */ 54259243Sobrien#include <warpdb.h> 54359243Sobrien#include <sys/warp.h> 54459243Sobrien 54559243Sobrienstatic jmp_buf sigsys_buf; 54659243Sobrien 547167465Smpstatic void 548167465Smpcatch_sigsys(void) 54959243Sobrien{ 550167465Smp sigset_t set; 551167465Smp sigemptyset(&set, SIGSYS); 552167465Smp (void)sigprocmask(SIG_UNBLOCK, &set, NULL); 55359243Sobrien longjmp(sigsys_buf, 1); 55459243Sobrien} 55559243Sobrien 55659243Sobrien 55759243Sobrien/*ARGSUSED*/ 55859243Sobrienvoid 559167465Smpdowarp(Char **v, struct command *c) 56059243Sobrien{ 56159243Sobrien int warp, oldwarp; 56259243Sobrien struct warpent *we; 563167465Smp volatile struct sigaction old_sigsys_handler; 56459243Sobrien char *newwarp; 56559243Sobrien 56659243Sobrien if (setjmp(sigsys_buf)) { 567167465Smp sigaction(SIGSYS, &old_sigsys_handler, NULL); 568167465Smp stderror(ERR_NAME | ERR_STRING, 56959243Sobrien CGETS(23, 8, "You're trapped in a universe you never made")); 57059243Sobrien return; 57159243Sobrien } 572167465Smp sigaction(SIGSYS, NULL, &old_sigsys_handler); 573167465Smp signal(SIGSYS, catch_sigsys); 57459243Sobrien 57559243Sobrien warp = getwarp(); 57659243Sobrien 57759243Sobrien v++; 57859243Sobrien if (*v == 0) { /* display warp value */ 57959243Sobrien if (warp < 0) 58059243Sobrien stderror(ERR_NAME | ERR_STRING, CGETS(23, 9, "Getwarp failed")); 58159243Sobrien we = getwarpbyvalue(warp); 58259243Sobrien if (we) 58359243Sobrien printf("%s\n", we->w_name); 58459243Sobrien else 58559243Sobrien printf("%d\n", warp); 58659243Sobrien } 58759243Sobrien else { /* set warp value */ 58859243Sobrien oldwarp = warp; 58959243Sobrien newwarp = short2str(*v); 59059243Sobrien if (Isdigit(*v[0])) 59159243Sobrien warp = atoi(newwarp); 59259243Sobrien else { 59359243Sobrien we = getwarpbyname(newwarp); 59459243Sobrien if (we) 59559243Sobrien warp = we->w_value; 59659243Sobrien else 59759243Sobrien warp = -1; 59859243Sobrien } 59959243Sobrien if ((warp < 0) || (warp >= WARP_MAXLINK)) 60059243Sobrien stderror(ERR_NAME | ERR_STRING, CGETS(23, 10, "Invalid warp")); 60159243Sobrien if ((setwarp(warp) < 0) || (getwarp() != warp)) { 60259243Sobrien (void) setwarp(oldwarp); 60359243Sobrien stderror(ERR_NAME | ERR_STRING, CGETS(23, 11, "Setwarp failed")); 60459243Sobrien } 60559243Sobrien } 606167465Smp sigaction(SIGSYS, &old_sigsys_handler, NULL); 60759243Sobrien} 60859243Sobrien#endif /* WARP */ 60959243Sobrien 61059243Sobrien/*** 61159243Sobrien *** Masscomp or HCX 61259243Sobrien ***/ 61359243Sobrien/* Added, DAS DEC-90. */ 61459243Sobrien#if defined(masscomp) || defined(_CX_UX) 615167465Smpstatic void 616167465Smpsetuniverse_cleanup(void *xbuf) 617167465Smp{ 618167465Smp char *buf; 619167465Smp 620167465Smp buf = xbuf; 621167465Smp setuniverse(buf); 622167465Smp} 623167465Smp 62459243Sobrien/*ARGSUSED*/ 62559243Sobrienvoid 626167465Smpdouniverse(Char **v, struct command *c) 62759243Sobrien{ 628145479Smp Char *cp = v[1]; 629145479Smp Char *cp2; /* dunno how many elements v comes in with */ 63059243Sobrien char ubuf[100]; 63159243Sobrien 63259243Sobrien if (cp == 0) { 63359243Sobrien (void) getuniverse(ubuf); 63459243Sobrien xprintf("%s\n", ubuf); 63559243Sobrien } 63659243Sobrien else { 63759243Sobrien cp2 = v[2]; 63859243Sobrien if (cp2 == 0) { 63959243Sobrien if (*cp == '\0' || setuniverse(short2str(cp)) != 0) 64059243Sobrien stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe")); 64159243Sobrien } 64259243Sobrien else { 64359243Sobrien (void) getuniverse(ubuf); 64459243Sobrien if (*cp == '\0' || setuniverse(short2str(cp)) != 0) 645167465Smp stderror(ERR_NAME | ERR_STRING, CGETS(23, 12, "Illegal universe")); 646167465Smp cleanup_push(ubuf, setuniverse_cleanup); 647167465Smp if (setintr) { 648167465Smp pintr_disabled++; 649167465Smp cleanup_push(&pintr_disabled, disabled_cleanup); 650167465Smp } 65159243Sobrien lshift(v, 2); 65259243Sobrien if (setintr) 653167465Smp cleanup_until(&pintr_disabled); 65459243Sobrien reexecute(c); 655167465Smp cleanup_until(ubuf); 65659243Sobrien } 65759243Sobrien } 65859243Sobrien} 65959243Sobrien#endif /* masscomp || _CX_UX */ 66059243Sobrien 661131962Smp/*** 662131962Smp *** BS2000/OSD POSIX (Fujitsu Siemens Computers) 663131962Smp ***/ 664131962Smp#if defined(_OSD_POSIX) 665131962Smpstatic int 666131962Smpbs2upcase(char *str) 667131962Smp{ 668131962Smp enum { outside = ' ', singlequote='\'', doublequote='"'} string = outside; 669131962Smp 670131962Smp char *white; 671131962Smp 672131962Smp for (white = str + strlen(str) - 1; isspace(*white) && white > str; --white) 673131962Smp *white = '\0'; 674131962Smp 675131962Smp for (; *str != '\0'; ++str) 676131962Smp { 677131962Smp if (string == outside) 678131962Smp { 679131962Smp *str = toupper (*str); 680131962Smp } 681131962Smp if (*str == '\'') 682131962Smp { 683131962Smp if (string == outside) 684131962Smp string = singlequote; 685131962Smp else if (string != doublequote) 686131962Smp string = outside; 687131962Smp } 688131962Smp else if (*str == '"') 689131962Smp { 690131962Smp if (string == outside) 691131962Smp string = doublequote; 692131962Smp else if (string != singlequote) 693131962Smp string = outside; 694131962Smp } 695131962Smp } 696131962Smp if (string != outside) 697131962Smp { 698131962Smp stderror(ERR_NAME | ERR_UNMATCHED, (Char) string); 699131962Smp return 1; 700131962Smp } 701131962Smp return 0; 702131962Smp} 703131962Smpstatic int 704131962Smpbs2cmdlist(char *str) 705131962Smp{ 706131962Smp char *str_beg = NULL; 707131962Smp int ret = 0; 708131962Smp 709131962Smp enum { outside = ' ', singlequote='\'', doublequote='"'} string = outside; 710131962Smp 711131962Smp while (*str != '\0') 712131962Smp { 713131962Smp while (isspace(*str)) 714131962Smp ++str; 715131962Smp 716131962Smp if (*str == '\0') 717131962Smp break; 718131962Smp 719131962Smp str_beg = str; 720131962Smp 721131962Smp for (; *str != '\0'; ++str) 722131962Smp { 723131962Smp if (string == outside && *str == ';') /* End of command */ 724131962Smp { 725131962Smp *str++ = '\0'; 726131962Smp break; /* continue with next command */ 727131962Smp } 728131962Smp if (*str == '\'') 729131962Smp { 730131962Smp if (string == outside) 731131962Smp string = singlequote; 732131962Smp else if (string != doublequote) 733131962Smp string = outside; 734131962Smp } 735131962Smp else if (*str == '"') 736131962Smp { 737131962Smp if (string == outside) 738131962Smp string = doublequote; 739131962Smp else if (string != singlequote) 740131962Smp string = outside; 741131962Smp } 742131962Smp } 743131962Smp if (strlen(str_beg) != 0) 744131962Smp { 745131962Smp ret = bs2system(str_beg); 746131962Smp flush(); 747131962Smp if (ret != 0 /*&& !option.err_ignore*/) 748131962Smp break; /* do not continue after errors */ 749131962Smp } 750131962Smp } 751131962Smp 752131962Smp if (string != outside) 753131962Smp { 754131962Smp stderror(ERR_NAME | ERR_UNMATCHED, (Char) string); 755131962Smp return -1; 756131962Smp } 757131962Smp 758131962Smp return ret; 759131962Smp} 760131962Smp/*ARGSUSED*/ 761131962Smpvoid 762167465Smpdobs2cmd(Char **v, struct command *c) 763131962Smp{ 764167465Smp Char *cp, **globbed; 765145479Smp int i = 0, len = 0; 766131962Smp char *cmd = NULL; 767131962Smp int pvec[2]; 768131962Smp struct command faket; 769131962Smp Char *fakecom[2]; 770131962Smp char tibuf[BUFSIZE]; 771167465Smp int icnt, old_pintr_disabled; 772131962Smp static const Char STRbs2cmd[] = { 'b','s','2','c','m','d','\0' }; 773131962Smp 774167465Smp v++; 775131962Smp if (setintr) 776167465Smp pintr_push_enable(&old_pintr_disabled); 777167465Smp v = glob_all_or_error(v); 778167465Smp if (setintr) 779167465Smp cleanup_until(&old_pintr_disabled); 780167465Smp globbed = v; 781167465Smp cleanup_push(globbed, blk_cleanup); 782131962Smp 783131962Smp /* First round: count the string lengths */ 784131962Smp for (i=0; v[i]; ++i) { 785167465Smp len += Strlen(v[i]) + (v[i+1] != NULL); 786131962Smp } 787131962Smp 788167465Smp cmd = xmalloc(len+1); /* 1 for the final '\0' *//* FIXME: memory leak? */ 789131962Smp 790131962Smp /* 2nd round: fill cmd buffer */ 791131962Smp i = 0; 792131962Smp while ((cp = *v++) != 0) { 793145479Smp int c; 794131962Smp while (c = *cp++) 795131962Smp cmd[i++] = (char)c; 796131962Smp if (*v) 797131962Smp cmd[i++] = ' '; 798131962Smp } 799131962Smp cmd[i] = '\0'; 800131962Smp 801131962Smp /* Make upper case */ 802131962Smp bs2upcase(cmd); 803131962Smp 804131962Smp faket.t_dtyp = NODE_COMMAND; 805131962Smp faket.t_dflg = F_BACKQ|F_STDERR; 806131962Smp faket.t_dlef = 0; 807131962Smp faket.t_drit = 0; 808131962Smp faket.t_dspr = 0; 809131962Smp faket.t_dcom = fakecom; 810167465Smp fakecom[0] = (Char *)STRbs2cmd; 811131962Smp fakecom[1] = 0; 812131962Smp 813131962Smp mypipe(pvec); 814167465Smp cleanup_push(&pvec[0], open_cleanup); 815167465Smp cleanup_push(&pvec[1], open_cleanup); 816131962Smp if (pfork(&faket, -1) == 0) { 817167465Smp sigset_t set; 818131962Smp /* child */ 819167465Smp xclose(pvec[0]); 820131962Smp (void) dmove(pvec[1], 1); 821131962Smp (void) dmove(SHDIAG, 2); 822131962Smp initdesc(); 823167465Smp sigemptyset(&set); 824167465Smp sigaddset(&set, SIGINT); 825167465Smp (void)sigprocmask(SIG_UNBLOCK, &set, NULL); 826131962Smp#ifdef SIGTSTP 827167465Smp signal(SIGTSTP, SIG_IGN); 828131962Smp#endif 829131962Smp#ifdef SIGTTIN 830167465Smp signal(SIGTTIN, SIG_IGN); 831131962Smp#endif 832131962Smp#ifdef SIGTTOU 833167465Smp signal(SIGTTOU, SIG_IGN); 834131962Smp#endif 835131962Smp xexit(bs2cmdlist(cmd)); 836131962Smp } 837167465Smp cleanup_until(&pvec[1]); 838131962Smp for(;;) { 839167465Smp int old_pintr_disabled; 840167465Smp 841167465Smp if (setintr) 842167465Smp pintr_push_enable(&old_pintr_disabled); 843167465Smp icnt = xread(pvec[0], tibuf, sizeof(tibuf)); 844167465Smp if (setintr) 845167465Smp cleanup_until(&old_pintr_disabled); 846131962Smp if (icnt <= 0) 847131962Smp break; 848131962Smp for (i = 0; i < icnt; i++) 849131962Smp xputchar((unsigned char) tibuf[i]); 850131962Smp } 851167465Smp cleanup_until(&pvec[0]); 852131962Smp pwait(); 853131962Smp 854131962Smp flush(); 855131962Smp 856167465Smp cleanup_until(globbed); 857131962Smp} 858131962Smp#endif /* _OSD_POSIX */ 859131962Smp 86059243Sobrien#if defined(_CX_UX) 861167465Smpstatic void 862167465Smpsetuniverse_cleanup(void *xbuf) 863167465Smp{ 864167465Smp char *buf; 865167465Smp 866167465Smp buf = xbuf; 867167465Smp setuniverse(buf); 868167465Smp} 869167465Smp 87059243Sobrien/*ARGSUSED*/ 87159243Sobrienvoid 872167465Smpdoatt(Char **v, struct command *c) 87359243Sobrien{ 874145479Smp Char *cp = v[1]; 87559243Sobrien char ubuf[100]; 87659243Sobrien 87759243Sobrien if (cp == 0) 87859243Sobrien (void) setuniverse("att"); 87959243Sobrien else { 88059243Sobrien (void) getuniverse(ubuf); 88159243Sobrien (void) setuniverse("att"); 882167465Smp cleanup_push(ubuf, setuniverse_cleanup); 883167465Smp if (setintr) { 884167465Smp pintr_disabled++; 885167465Smp cleanup_push(&pintr_disabled, disabled_cleanup); 886167465Smp } 88759243Sobrien lshift(v, 1); 88859243Sobrien if (setintr) 889167465Smp cleanup_until(&pintr_disabled); 89059243Sobrien reexecute(c); 891167465Smp cleanup_until(ubuf); 89259243Sobrien } 89359243Sobrien} 89459243Sobrien 89559243Sobrien/*ARGSUSED*/ 89659243Sobrienvoid 897167465Smpdoucb(Char **v, struct command *c) 89859243Sobrien{ 899145479Smp Char *cp = v[1]; 90059243Sobrien char ubuf[100]; 90159243Sobrien 90259243Sobrien if (cp == 0) 90359243Sobrien (void) setuniverse("ucb"); 90459243Sobrien else { 90559243Sobrien (void) getuniverse(ubuf); 90659243Sobrien (void) setuniverse("ucb"); 907167465Smp cleanup_push(ubuf, setuniverse_cleanup); 908167465Smp if (setintr) { 909167465Smp pintr_disabled++; 910167465Smp cleanup_push(&pintr_disabled, disabled_cleanup); 911167465Smp } 91259243Sobrien lshift(v, 1); 91359243Sobrien if (setintr) 914167465Smp cleanup_until(&pintr_disabled); 91559243Sobrien reexecute(c); 916167465Smp cleanup_until(ubuf); 91759243Sobrien } 91859243Sobrien} 91959243Sobrien#endif /* _CX_UX */ 92059243Sobrien 92159243Sobrien#ifdef _SEQUENT_ 92259243Sobrien/* 92359243Sobrien * Compute the difference in process stats. 92459243Sobrien */ 92559243Sobrienvoid 926167465Smppr_stat_sub(struct process_stats *p2, struct process_stats *p1, 927167465Smp struct process_stats *pr) 92859243Sobrien{ 92959243Sobrien pr->ps_utime.tv_sec = p2->ps_utime.tv_sec - p1->ps_utime.tv_sec; 93059243Sobrien pr->ps_utime.tv_usec = p2->ps_utime.tv_usec - p1->ps_utime.tv_usec; 93159243Sobrien if (pr->ps_utime.tv_usec < 0) { 93259243Sobrien pr->ps_utime.tv_sec -= 1; 93359243Sobrien pr->ps_utime.tv_usec += 1000000; 93459243Sobrien } 93559243Sobrien pr->ps_stime.tv_sec = p2->ps_stime.tv_sec - p1->ps_stime.tv_sec; 93659243Sobrien pr->ps_stime.tv_usec = p2->ps_stime.tv_usec - p1->ps_stime.tv_usec; 93759243Sobrien if (pr->ps_stime.tv_usec < 0) { 93859243Sobrien pr->ps_stime.tv_sec -= 1; 93959243Sobrien pr->ps_stime.tv_usec += 1000000; 94059243Sobrien } 94159243Sobrien 94259243Sobrien pr->ps_maxrss = p2->ps_maxrss - p1->ps_maxrss; 94359243Sobrien pr->ps_pagein = p2->ps_pagein - p1->ps_pagein; 94459243Sobrien pr->ps_reclaim = p2->ps_reclaim - p1->ps_reclaim; 94559243Sobrien pr->ps_zerofill = p2->ps_zerofill - p1->ps_zerofill; 94659243Sobrien pr->ps_pffincr = p2->ps_pffincr - p1->ps_pffincr; 94759243Sobrien pr->ps_pffdecr = p2->ps_pffdecr - p1->ps_pffdecr; 94859243Sobrien pr->ps_swap = p2->ps_swap - p1->ps_swap; 94959243Sobrien pr->ps_syscall = p2->ps_syscall - p1->ps_syscall; 95059243Sobrien pr->ps_volcsw = p2->ps_volcsw - p1->ps_volcsw; 95159243Sobrien pr->ps_involcsw = p2->ps_involcsw - p1->ps_involcsw; 95259243Sobrien pr->ps_signal = p2->ps_signal - p1->ps_signal; 95359243Sobrien pr->ps_lread = p2->ps_lread - p1->ps_lread; 95459243Sobrien pr->ps_lwrite = p2->ps_lwrite - p1->ps_lwrite; 95559243Sobrien pr->ps_bread = p2->ps_bread - p1->ps_bread; 95659243Sobrien pr->ps_bwrite = p2->ps_bwrite - p1->ps_bwrite; 95759243Sobrien pr->ps_phread = p2->ps_phread - p1->ps_phread; 95859243Sobrien pr->ps_phwrite = p2->ps_phwrite - p1->ps_phwrite; 95959243Sobrien} 96059243Sobrien 96159243Sobrien#endif /* _SEQUENT_ */ 96259243Sobrien 96359243Sobrien 964145479Smp#ifndef HAVE_MEMSET 96559243Sobrien/* This is a replacement for a missing memset function */ 966167465Smpvoid *xmemset(void *loc, int value, size_t len) 96759243Sobrien{ 968167465Smp char *ptr = loc; 969167465Smp 97059243Sobrien while (len--) 97159243Sobrien *ptr++ = value; 97259243Sobrien return loc; 97359243Sobrien} 974145479Smp#endif /* !HAVE_MEMSET */ 97559243Sobrien 97659243Sobrien 977145479Smp#ifndef HAVE_MEMMOVE 97859243Sobrien/* memmove(): 97959243Sobrien * This is the ANSI form of bcopy() with the arguments backwards... 98059243Sobrien * Unlike memcpy(), it handles overlaps between source and 98159243Sobrien * destination memory 98259243Sobrien */ 983167465Smpvoid * 984167465Smpxmemmove(void *vdst, const void *vsrc, size_t len) 98559243Sobrien{ 986167465Smp const char *src = vsrc; 987167465Smp char *dst = vdst; 98859243Sobrien 98959243Sobrien if (src == dst) 99059243Sobrien return vdst; 99159243Sobrien 99259243Sobrien if (src > dst) { 99359243Sobrien while (len--) 99459243Sobrien *dst++ = *src++; 99559243Sobrien } 99659243Sobrien else { 99759243Sobrien src += len; 99859243Sobrien dst += len; 99959243Sobrien while (len--) 100059243Sobrien *--dst = *--src; 100159243Sobrien } 100259243Sobrien return vdst; 100359243Sobrien} 1004145479Smp#endif /* HAVE_MEMMOVE */ 100559243Sobrien 100659243Sobrien 100769408Sache#ifndef WINNT_NATIVE 1008145479Smp#ifdef NEEDtcgetpgrp 1009167465Smppid_t 1010167465Smpxtcgetpgrp(int fd) 101159243Sobrien{ 101259243Sobrien int pgrp; 101359243Sobrien 101459243Sobrien /* ioctl will handle setting errno correctly. */ 101559243Sobrien if (ioctl(fd, TIOCGPGRP, (ioctl_t) & pgrp) < 0) 101659243Sobrien return (-1); 101759243Sobrien return (pgrp); 101859243Sobrien} 101959243Sobrien 102059243Sobrien/* 102159243Sobrien * XXX: tcsetpgrp is not a macro any more cause on some systems, 102259243Sobrien * pid_t is a short, but the ioctl() takes a pointer to int (pyr) 102359243Sobrien * Thanks to Simon Day (simon@pharaoh.cyborg.bt.co.uk) for pointing 102459243Sobrien * this out. 102559243Sobrien */ 102659243Sobrienint 1027167465Smpxtcsetpgrp(int fd, int pgrp) 102859243Sobrien{ 102959243Sobrien return ioctl(fd, TIOCSPGRP, (ioctl_t) &pgrp); 103059243Sobrien} 103159243Sobrien 1032145479Smp#endif /* NEEDtcgetpgrp */ 103369408Sache#endif /* WINNT_NATIVE */ 103459243Sobrien 103559243Sobrien 103659243Sobrien#ifdef YPBUGS 103759243Sobrienvoid 1038167465Smpfix_yp_bugs(void) 103959243Sobrien{ 104059243Sobrien char *mydomain; 104159243Sobrien 1042167465Smp extern int yp_get_default_domain (char **); 104359243Sobrien /* 104459243Sobrien * PWP: The previous version assumed that yp domain was the same as the 104559243Sobrien * internet name domain. This isn't allways true. (Thanks to Mat Landau 104659243Sobrien * <mlandau@bbn.com> for the original version of this.) 104759243Sobrien */ 104859243Sobrien if (yp_get_default_domain(&mydomain) == 0) { /* if we got a name */ 1049167465Smp extern void yp_unbind (const char *); 105059243Sobrien 105159243Sobrien yp_unbind(mydomain); 105259243Sobrien } 105359243Sobrien} 105459243Sobrien 105559243Sobrien#endif /* YPBUGS */ 105659243Sobrien 105759243Sobrien#ifdef STRCOLLBUG 105859243Sobrienvoid 1059167465Smpfix_strcoll_bug(void) 106059243Sobrien{ 1061167465Smp#if defined(NLS) && defined(HAVE_STRCOLL) 106259243Sobrien /* 106359243Sobrien * SunOS4 checks the file descriptor from openlocale() for <= 0 106459243Sobrien * instead of == -1. Someone should tell sun that file descriptor 0 106559243Sobrien * is valid! Our portable hack: open one so we call it with 0 used... 106659243Sobrien * We have to call this routine every time the locale changes... 106759243Sobrien * 106859243Sobrien * Of course it also tries to free the constant locale "C" it initially 106959243Sobrien * had allocated, with the sequence 107059243Sobrien * > setenv LANG "fr" 107159243Sobrien * > ls^D 107259243Sobrien * > unsetenv LANG 107359243Sobrien * But we are smarter than that and just print a warning message. 107459243Sobrien */ 107559243Sobrien int fd = -1; 107659243Sobrien static char *root = "/"; 107759243Sobrien 107859243Sobrien if (!didfds) 1079167465Smp fd = xopen(root, O_RDONLY|O_LARGEFILE); 108059243Sobrien 108159243Sobrien (void) strcoll(root, root); 108259243Sobrien 108359243Sobrien if (fd != -1) 1084167465Smp xclose(fd); 108559243Sobrien#endif 108659243Sobrien} 108759243Sobrien#endif /* STRCOLLBUG */ 108859243Sobrien 108959243Sobrien 109059243Sobrien#ifdef OREO 109159243Sobrien#include <compat.h> 109259243Sobrien#endif /* OREO */ 109359243Sobrien 109459243Sobrienvoid 1095167465Smposinit(void) 109659243Sobrien{ 109759243Sobrien#ifdef OREO 109859243Sobrien set42sig(); 109959243Sobrien setcompat(getcompat() & ~COMPAT_EXEC); 1100167465Smp signal(SIGIO, SIG_IGN); /* ignore SIGIO */ 110159243Sobrien#endif /* OREO */ 110259243Sobrien 110359243Sobrien#ifdef aiws 110459243Sobrien { 110559243Sobrien struct sigstack inst; 1106167465Smp inst.ss_sp = xmalloc(4192) + 4192; 110759243Sobrien inst.ss_onstack = 0; 110859243Sobrien sigstack(&inst, NULL); 110959243Sobrien } 111059243Sobrien#endif /* aiws */ 111159243Sobrien 111259243Sobrien#ifdef apollo 111359243Sobrien (void) isapad(); 111459243Sobrien#endif 111559243Sobrien 111659243Sobrien#ifdef _SX 111759243Sobrien /* 111859243Sobrien * kill(SIGCONT) problems, don't know what this syscall does 111959243Sobrien * [schott@rzg.mpg.de] 112059243Sobrien */ 112159243Sobrien syscall(151, getpid(), getpid()); 112259243Sobrien#endif /* _SX */ 112359243Sobrien} 112459243Sobrien 1125145479Smp#ifndef HAVE_STRERROR 1126167465Smpextern int sys_nerr; 1127167465Smpextern char *sys_errlist[]; 112859243Sobrienchar * 1129167465Smpxstrerror(int i) 113059243Sobrien{ 113159243Sobrien if (i >= 0 && i < sys_nerr) { 113259243Sobrien return sys_errlist[i]; 113359243Sobrien } else { 1134167465Smp static char *errbuf; /* = NULL; */ 1135167465Smp 1136167465Smp xfree(errbuf); 1137167465Smp errbuf = xasprintf(CGETS(23, 13, "Unknown Error: %d"), i); 113859243Sobrien return errbuf; 113959243Sobrien } 114059243Sobrien} 1141145479Smp#endif /* !HAVE_STRERROR */ 114259243Sobrien 1143145479Smp#ifndef HAVE_GETHOSTNAME 114469408Sache# if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE) 114559243Sobrien# include <sys/utsname.h> 114669408Sache# endif /* !_MINIX && !__EMX__ && !WINNT_NATIVE */ 114759243Sobrien 114859243Sobrienint 1149167465Smpxgethostname(char *name, int namlen) 115059243Sobrien{ 115169408Sache# if !defined(_MINIX) && !defined(__EMX__) && !defined(WINNT_NATIVE) 115259243Sobrien int i, retval; 115359243Sobrien struct utsname uts; 115459243Sobrien 115559243Sobrien retval = uname(&uts); 115659243Sobrien 115759243Sobrien# ifdef DEBUG 115859243Sobrien xprintf(CGETS(23, 14, "sysname: %s\n"), uts.sysname); 115959243Sobrien xprintf(CGETS(23, 15, "nodename: %s\n"), uts.nodename); 116059243Sobrien xprintf(CGETS(23, 16, "release: %s\n"), uts.release); 116159243Sobrien xprintf(CGETS(23, 17, "version: %s\n"), uts.version); 116259243Sobrien xprintf(CGETS(23, 18, "machine: %s\n"), uts.machine); 116359243Sobrien# endif /* DEBUG */ 116459243Sobrien i = strlen(uts.nodename) + 1; 116559243Sobrien (void) strncpy(name, uts.nodename, i < namlen ? i : namlen); 116659243Sobrien 116759243Sobrien return retval; 116859243Sobrien# else /* !_MINIX && !__EMX__ */ 116959243Sobrien if (namlen > 0) { 117059243Sobrien# ifdef __EMX__ 117159243Sobrien (void) strncpy(name, "OS/2", namlen); 117259243Sobrien# else /* _MINIX */ 117359243Sobrien (void) strncpy(name, "minix", namlen); 117459243Sobrien# endif /* __EMX__ */ 117559243Sobrien name[namlen-1] = '\0'; 117659243Sobrien } 117759243Sobrien return(0); 117859243Sobrien#endif /* _MINIX && !__EMX__ */ 117959243Sobrien} /* end xgethostname */ 1180145479Smp#endif /* !HAVE_GETHOSTNAME */ 118159243Sobrien 1182145479Smp#ifndef HAVE_NICE 118359243Sobrien# if defined(_MINIX) && defined(NICE) 118459243Sobrien# undef _POSIX_SOURCE /* redefined in <lib.h> */ 118559243Sobrien# undef _MINIX /* redefined in <lib.h> */ 118659243Sobrien# undef HZ /* redefined in <minix/const.h> */ 118759243Sobrien# include <lib.h> 118859243Sobrien# endif /* _MINIX && NICE */ 118959243Sobrienint 1190167465Smpxnice(int incr) 119159243Sobrien{ 119259243Sobrien#if defined(_MINIX) && defined(NICE) 119359243Sobrien return callm1(MM, NICE, incr, 0, 0, NIL_PTR, NIL_PTR, NIL_PTR); 119459243Sobrien#else 119559243Sobrien return /* incr ? 0 : */ 0; 119659243Sobrien#endif /* _MINIX && NICE */ 119759243Sobrien} /* end xnice */ 1198145479Smp#endif /* !HAVE_NICE */ 119959243Sobrien 1200145479Smp#ifndef HAVE_GETCWD 1201167465Smpstatic char *strnrcpy (char *, char *, size_t); 120259243Sobrien 120359243Sobrien/* xgetcwd(): 120459243Sobrien * Return the pathname of the current directory, or return 120559243Sobrien * an error message in pathname. 120659243Sobrien */ 120759243Sobrien 120859243Sobrien# ifdef hp9000s500 120959243Sobrien/* 121059243Sobrien * From: Bernd Mohr <mohr@faui77.informatik.uni-erlangen.de> 121159243Sobrien * I also ported the tcsh to the HP9000 Series 500. This computer 121259243Sobrien * is a little bit different than the other HP 9000 computer. It has 121359243Sobrien * a HP Chip instead of a Motorola CPU and it is no "real" UNIX. It runs 121459243Sobrien * HP-UX which is emulated in top of a HP operating system. So, the last 121559243Sobrien * supported version of HP-UX is 5.2 on the HP9000s500. This has two 121659243Sobrien * consequences: it supports no job control and it has a filesystem 121759243Sobrien * without "." and ".." !!! 121859243Sobrien */ 121959243Sobrienchar * 1220167465Smpxgetcwd(char *pathname, size_t pathlen) 122159243Sobrien{ 1222167465Smp char pathbuf[MAXPATHLEN]; /* temporary pathname buffer */ 122359243Sobrien char *pnptr = &pathbuf[(sizeof pathbuf)-1]; /* pathname pointer */ 122459243Sobrien dev_t rdev; /* root device number */ 122559243Sobrien DIR *dirp = NULL; /* directory stream */ 122659243Sobrien ino_t rino; /* root inode number */ 122759243Sobrien off_t rsize; /* root size */ 122859243Sobrien struct direct *dir; /* directory entry struct */ 122959243Sobrien struct stat d, dd; /* file status struct */ 123059243Sobrien int serrno; 123159243Sobrien 123259243Sobrien *pnptr = '\0'; 123359243Sobrien (void) stat("/.", &d); 123459243Sobrien rdev = d.st_dev; 123559243Sobrien rino = d.st_ino; 123659243Sobrien rsize = d.st_size; 123759243Sobrien for (;;) { 123859243Sobrien if (stat(".", &d) == -1) { 123959243Sobrien (void) xsnprintf(pathname, pathlen, CGETS(23, 24, 124059243Sobrien "getcwd: Cannot stat \".\" (%s)"), strerror(errno)); 124159243Sobrien goto fail; 124259243Sobrien } 124359243Sobrien if (d.st_ino == rino && d.st_dev == rdev && d.st_size == rsize) 124459243Sobrien break; /* reached root directory */ 124559243Sobrien if ((dirp = opendir("..")) == NULL) { 124659243Sobrien (void) xsnprintf(pathname, pathlen, CGETS(23, 19, 124759243Sobrien "getcwd: Cannot open \"..\" (%s)"), strerror(errno)); 124859243Sobrien goto fail; 124959243Sobrien } 125059243Sobrien if (chdir("..") == -1) { 125159243Sobrien (void) xsnprintf(pathname, pathlen, CGETS(23, 20, 125259243Sobrien "getcwd: Cannot chdir to \"..\" (%s)"), strerror(errno)); 125359243Sobrien goto fail; 125459243Sobrien } 125559243Sobrien do { 125659243Sobrien if ((dir = readdir(dirp)) == NULL) { 125759243Sobrien (void) xsnprintf(pathname, pathlen, 125859243Sobrien CGETS(23, 21, "getcwd: Read error in \"..\" (%s)"), 125959243Sobrien strerror(errno)); 126059243Sobrien goto fail; 126159243Sobrien } 126259243Sobrien if (stat(dir->d_name, &dd) == -1) { 126359243Sobrien (void) xsnprintf(pathname, pathlen, 126459243Sobrien CGETS(23, 25, "getcwd: Cannot stat directory \"%s\" (%s)"), 126559243Sobrien dir->d_name, strerror(errno)); 126659243Sobrien goto fail; 126759243Sobrien } 126859243Sobrien } while (dd.st_ino != d.st_ino || 126959243Sobrien dd.st_dev != d.st_dev || 127059243Sobrien dd.st_size != d.st_size); 1271167465Smp closedir(dirp); 127259243Sobrien dirp = NULL; 127359243Sobrien pnptr = strnrcpy(dirp->d_name, pnptr, pnptr - pathbuf); 127459243Sobrien pnptr = strnrcpy("/", pnptr, pnptr - pathbuf); 127559243Sobrien } 127659243Sobrien 127759243Sobrien if (*pnptr == '\0') /* current dir == root dir */ 127859243Sobrien (void) strncpy(pathname, "/", pathlen); 127959243Sobrien else { 128059243Sobrien (void) strncpy(pathname, pnptr, pathlen); 128159243Sobrien pathname[pathlen - 1] = '\0'; 128259243Sobrien if (chdir(pnptr) == -1) { 128359243Sobrien (void) xsnprintf(pathname, MAXPATHLEN, CGETS(23, 22, 128459243Sobrien "getcwd: Cannot change back to \".\" (%s)"), 128559243Sobrien strerror(errno)); 128659243Sobrien return NULL; 128759243Sobrien } 128859243Sobrien } 128959243Sobrien return pathname; 129059243Sobrien 129159243Sobrienfail: 129259243Sobrien serrno = errno; 129359243Sobrien (void) chdir(strnrcpy(".", pnptr, pnptr - pathbuf)); 129459243Sobrien errno = serrno; 129559243Sobrien return NULL; 129659243Sobrien} 129759243Sobrien 129859243Sobrien# else /* ! hp9000s500 */ 129959243Sobrien 130059243Sobrien 130159243Sobrienchar * 1302167465Smpxgetcwd(char *pathname, size_t pathlen) 130359243Sobrien{ 130459243Sobrien DIR *dp; 130559243Sobrien struct dirent *d; 130659243Sobrien 130759243Sobrien struct stat st_root, st_cur, st_next, st_dotdot; 130859243Sobrien char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; 130959243Sobrien char *pathptr, *nextpathptr, *cur_name_add; 131059243Sobrien int save_errno = 0; 131159243Sobrien 131259243Sobrien /* find the inode of root */ 131359243Sobrien if (stat("/", &st_root) == -1) { 131459243Sobrien (void) xsnprintf(pathname, pathlen, CGETS(23, 23, 131559243Sobrien "getcwd: Cannot stat \"/\" (%s)"), 131659243Sobrien strerror(errno)); 131759243Sobrien return NULL; 131859243Sobrien } 131959243Sobrien pathbuf[MAXPATHLEN - 1] = '\0'; 132059243Sobrien pathptr = &pathbuf[MAXPATHLEN - 1]; 132159243Sobrien nextpathbuf[MAXPATHLEN - 1] = '\0'; 132259243Sobrien cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; 132359243Sobrien 132459243Sobrien /* find the inode of the current directory */ 132559243Sobrien if (lstat(".", &st_cur) == -1) { 132659243Sobrien (void) xsnprintf(pathname, pathlen, CGETS(23, 24, 132759243Sobrien "getcwd: Cannot stat \".\" (%s)"), 132859243Sobrien strerror(errno)); 132959243Sobrien return NULL; 133059243Sobrien } 133159243Sobrien nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf); 133259243Sobrien 133359243Sobrien /* Descend to root */ 133459243Sobrien for (;;) { 133559243Sobrien 133659243Sobrien /* look if we found root yet */ 133759243Sobrien if (st_cur.st_ino == st_root.st_ino && 133859243Sobrien DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { 133959243Sobrien (void) strncpy(pathname, *pathptr != '/' ? "/" : pathptr, pathlen); 134059243Sobrien pathname[pathlen - 1] = '\0'; 134159243Sobrien return pathname; 134259243Sobrien } 134359243Sobrien 134459243Sobrien /* open the parent directory */ 134559243Sobrien if (stat(nextpathptr, &st_dotdot) == -1) { 134659243Sobrien (void) xsnprintf(pathname, pathlen, CGETS(23, 25, 134759243Sobrien "getcwd: Cannot stat directory \"%s\" (%s)"), 134859243Sobrien nextpathptr, strerror(errno)); 134959243Sobrien return NULL; 135059243Sobrien } 135159243Sobrien if ((dp = opendir(nextpathptr)) == NULL) { 135259243Sobrien (void) xsnprintf(pathname, pathlen, CGETS(23, 26, 135359243Sobrien "getcwd: Cannot open directory \"%s\" (%s)"), 135459243Sobrien nextpathptr, strerror(errno)); 135559243Sobrien return NULL; 135659243Sobrien } 135759243Sobrien 135859243Sobrien /* look in the parent for the entry with the same inode */ 135959243Sobrien if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { 136059243Sobrien /* Parent has same device. No need to stat every member */ 136159243Sobrien for (d = readdir(dp); d != NULL; d = readdir(dp)) { 136259243Sobrien#ifdef __clipper__ 1363145479Smp if (((unsigned long)d->d_ino & 0xffff) == st_cur.st_ino) 136459243Sobrien break; 136559243Sobrien#else 1366145479Smp if (d->d_ino == st_cur.st_ino) 136759243Sobrien break; 136859243Sobrien#endif 136959243Sobrien } 137059243Sobrien } 137159243Sobrien else { 137259243Sobrien /* 137359243Sobrien * Parent has a different device. This is a mount point so we 137459243Sobrien * need to stat every member 137559243Sobrien */ 137659243Sobrien for (d = readdir(dp); d != NULL; d = readdir(dp)) { 137759243Sobrien if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) 137859243Sobrien continue; 137959243Sobrien (void)strncpy(cur_name_add, d->d_name, 138059243Sobrien (size_t) (&nextpathbuf[sizeof(nextpathbuf) - 1] - cur_name_add)); 138159243Sobrien if (lstat(nextpathptr, &st_next) == -1) { 138259243Sobrien /* 138359243Sobrien * We might not be able to stat() some path components 138459243Sobrien * if we are using afs, but this is not an error as 138559243Sobrien * long as we find the one we need; we also save the 138659243Sobrien * first error to report it if we don't finally succeed. 138759243Sobrien */ 138859243Sobrien if (save_errno == 0) 138959243Sobrien save_errno = errno; 139059243Sobrien continue; 139159243Sobrien } 139259243Sobrien /* check if we found it yet */ 139359243Sobrien if (st_next.st_ino == st_cur.st_ino && 139459243Sobrien DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) 139559243Sobrien break; 139659243Sobrien } 139759243Sobrien } 139859243Sobrien if (d == NULL) { 139959243Sobrien (void) xsnprintf(pathname, pathlen, CGETS(23, 27, 140059243Sobrien "getcwd: Cannot find \".\" in \"..\" (%s)"), 140159243Sobrien strerror(save_errno ? save_errno : ENOENT)); 1402167465Smp closedir(dp); 140359243Sobrien return NULL; 140459243Sobrien } 140559243Sobrien else 140659243Sobrien save_errno = 0; 140759243Sobrien st_cur = st_dotdot; 140859243Sobrien pathptr = strnrcpy(pathptr, d->d_name, pathptr - pathbuf); 140959243Sobrien pathptr = strnrcpy(pathptr, "/", pathptr - pathbuf); 141059243Sobrien nextpathptr = strnrcpy(nextpathptr, "../", nextpathptr - nextpathbuf); 141159243Sobrien *cur_name_add = '\0'; 1412167465Smp closedir(dp); 141359243Sobrien } 141459243Sobrien} /* end getcwd */ 141559243Sobrien# endif /* hp9000s500 */ 141659243Sobrien 141759243Sobrien/* strnrcpy(): 141859243Sobrien * Like strncpy, going backwards and returning the new pointer 141959243Sobrien */ 142059243Sobrienstatic char * 1421167465Smpstrnrcpy(char *ptr, char *str, size_t siz) 142259243Sobrien{ 1423145479Smp int len = strlen(str); 142459243Sobrien if (siz == 0) 142559243Sobrien return ptr; 142659243Sobrien 142759243Sobrien while (len && siz--) 142859243Sobrien *--ptr = str[--len]; 142959243Sobrien 143059243Sobrien return (ptr); 143159243Sobrien} /* end strnrcpy */ 1432145479Smp#endif /* !HAVE_GETCWD */ 143359243Sobrien 143459243Sobrien#ifdef apollo 143559243Sobrien/*** 143659243Sobrien *** Domain/OS 143759243Sobrien ***/ 143859243Sobrien#include <apollo/base.h> 143959243Sobrien#include <apollo/loader.h> 144059243Sobrien#include <apollo/error.h> 144159243Sobrien 144259243Sobrien 144359243Sobrienstatic char * 1444167465Smpapperr(status_$t *st) 144559243Sobrien{ 1446167465Smp static char *buf; /* = NULL */ 144759243Sobrien short e_subl, e_modl, e_codel; 144859243Sobrien error_$string_t e_sub, e_mod, e_code; 144959243Sobrien 145059243Sobrien error_$get_text(*st, e_sub, &e_subl, e_mod, &e_modl, e_code, &e_codel); 145159243Sobrien e_sub[e_subl] = '\0'; 145259243Sobrien e_code[e_codel] = '\0'; 145359243Sobrien e_mod[e_modl] = '\0'; 1454167465Smp xfree(buf); 1455167465Smp buf = xasprintf("%s (%s/%s)", e_code, e_sub, e_mod); 145659243Sobrien 145759243Sobrien return(buf); 145859243Sobrien} 145959243Sobrien 146059243Sobrienstatic int 1461167465Smpllib(Char *s) 146259243Sobrien{ 146359243Sobrien short len = Strlen(s); 146459243Sobrien status_$t st; 146559243Sobrien char *t; 146659243Sobrien 146759243Sobrien loader_$inlib(t = short2str(s), len, &st); 146859243Sobrien if (st.all != status_$ok) 146959243Sobrien stderror(ERR_SYSTEM, t, apperr(&st)); 147059243Sobrien} 147159243Sobrien 147259243Sobrien/*ARGSUSED*/ 147359243Sobrienvoid 1474167465Smpdoinlib(Char **v, struct command *c) 147559243Sobrien{ 1476167465Smp Char **globbed; 1477167465Smp 147859243Sobrien setname(short2str(*v++)); 1479167465Smp v = glob_all_or_error(v); 1480167465Smp globbed = v; 1481167465Smp cleanup_push(globbed, blk_cleanup); 148259243Sobrien 148359243Sobrien while (v && *v) 148459243Sobrien llib(*v++); 1485167465Smp cleanup_until(globbed); 148659243Sobrien} 148759243Sobrien 148859243Sobrienint 1489167465Smpgetv(Char *v) 149059243Sobrien{ 149159243Sobrien if (eq(v, STRbsd43)) 149259243Sobrien return(1); 149359243Sobrien else if (eq(v, STRsys53)) 149459243Sobrien return(0); 149559243Sobrien else 149659243Sobrien stderror(ERR_NAME | ERR_SYSTEM, short2str(v), 149759243Sobrien CGETS(23, 28, "Invalid system type")); 149859243Sobrien /*NOTREACHED*/ 149959243Sobrien return(0); 150059243Sobrien} 150159243Sobrien 150259243Sobrien/*ARGSUSED*/ 150359243Sobrienvoid 1504167465Smpdover(Char **v, struct command *c) 150559243Sobrien{ 150659243Sobrien Char *p; 150759243Sobrien 150859243Sobrien setname(short2str(*v++)); 150959243Sobrien if (!*v) { 151059243Sobrien if (!(p = tgetenv(STRSYSTYPE))) 151159243Sobrien stderror(ERR_NAME | ERR_STRING, 151259243Sobrien CGETS(23, 29, "System type is not set")); 151359243Sobrien xprintf("%S\n", p); 151459243Sobrien } 151559243Sobrien else { 151659243Sobrien tsetenv(STRSYSTYPE, getv(*v) ? STRbsd43 : STRsys53); 151759243Sobrien dohash(NULL, NULL); 151859243Sobrien } 151959243Sobrien} 152059243Sobrien 152159243Sobrien/* 152259243Sobrien * Many thanks to rees@citi.umich.edu (Jim Rees) and 152359243Sobrien * mathys@ssdt-tempe.sps.mot.com (Yves Mathys) 152459243Sobrien * For figuring out how to do this... I could have never done 152559243Sobrien * it without their help. 152659243Sobrien */ 152759243Sobrientypedef short enum { 152859243Sobrien name_$wdir_type, 152959243Sobrien name_$ndir_type, 153059243Sobrien name_$node_dir_type, 153159243Sobrien} name_$dir_type_t; 153259243Sobrien 153359243Sobrien/*ARGSUSED*/ 153459243Sobrienvoid 1535167465Smpdorootnode(Char **v, struct command *c) 153659243Sobrien{ 153759243Sobrien name_$dir_type_t dirtype = name_$node_dir_type; 153859243Sobrien uid_$t uid; 153959243Sobrien status_$t st; 154059243Sobrien char *name; 154159243Sobrien short namelen; 154259243Sobrien 154359243Sobrien setname(short2str(*v++)); 154459243Sobrien 154559243Sobrien name = short2str(*v); 154659243Sobrien namelen = strlen(name); 154759243Sobrien 154859243Sobrien name_$resolve(name, &namelen, &uid, &st); 154959243Sobrien if (st.all != status_$ok) 155059243Sobrien stderror(ERR_SYSTEM, name, apperr(&st)); 155159243Sobrien namelen = 0; 155259243Sobrien name_$set_diru(&uid, "", &namelen, &dirtype, &st); 155359243Sobrien if (st.all != status_$ok) 155459243Sobrien stderror(ERR_SYSTEM, name, apperr(&st)); 155559243Sobrien dohash(NULL, NULL); 155659243Sobrien} 155759243Sobrien 155859243Sobrienint 1559167465Smpisapad(void) 156059243Sobrien{ 156159243Sobrien static int res = -1; 156259243Sobrien static status_$t st; 156359243Sobrien 156459243Sobrien if (res == -1) { 156559243Sobrien int strm; 156659243Sobrien if (isatty(0)) 156759243Sobrien strm = 0; 156859243Sobrien if (isatty(1)) 156959243Sobrien strm = 1; 157059243Sobrien if (isatty(2)) 157159243Sobrien strm = 2; 157259243Sobrien else { 157359243Sobrien res = 0; 157459243Sobrien st.all = status_$ok; 157559243Sobrien return(res); 157659243Sobrien } 157759243Sobrien res = stream_$isavt(&strm, &st); 157859243Sobrien res = res ? 1 : 0; 157959243Sobrien } 158059243Sobrien else { 158159243Sobrien if (st.all != status_$ok) 158259243Sobrien stderror(ERR_SYSTEM, "stream_$isavt", apperr(&st)); 158359243Sobrien } 158459243Sobrien return(res); 158559243Sobrien} 158659243Sobrien#endif 1587232633Smp 1588232633Smp#ifdef __ANDROID__ 1589232633Smp#include <stdio.h> 1590232633Smp/* Android (<= 2.1?) has an incomplete ttyname implementation. */ 1591232633Smpchar * 1592232633Smpttyname(int fd) 1593232633Smp{ 1594232633Smp char path[64]; 1595232633Smp ssize_t siz; 1596232633Smp static char ttyname[32]; 1597232633Smp 1598232633Smp if (!isatty(fd)) 1599232633Smp return NULL; 1600232633Smp 1601232633Smp (void)snprintf(path, sizeof(path), "/proc/self/fd/%d", fd); 1602232633Smp siz = readlink(path, ttyname, sizeof(ttyname)); 1603232633Smp if (siz < 0 || siz == sizeof(ttyname)) 1604232633Smp return NULL; 1605232633Smp ttyname[siz] = '\0'; 1606232633Smp return ttyname; 1607232633Smp} 1608232633Smp#endif /* __ANDROID__ */ 1609232633Smp 1610232633Smp#if defined(__CYGWIN__) && !defined(NO_CRYPT) 1611232633Smp#undef CHAR /* Collides with Win32 API */ 1612232633Smp#define WIN32_LEAN_AND_MEAN 1613232633Smp#include <windows.h> 1614232633Smp#include <sys/cygwin.h> 1615232633Smpchar * 1616232633Smpcygwin_xcrypt(struct passwd *pw, const char *password, const char *expected_pwd) 1617232633Smp{ 1618232633Smp static char invalid_password[] = "\377"; 1619232633Smp HANDLE token = cygwin_logon_user(pw, password); 1620232633Smp if (token == INVALID_HANDLE_VALUE) 1621232633Smp return invalid_password; 1622232633Smp CloseHandle(token); 1623232633Smp return (char *) expected_pwd; 1624232633Smp} 1625232633Smp#endif /* __CYGWIN__ && !NO_CRYPT */ 1626