source: trunk/third/tcsh/tc.os.c @ 12039

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