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