Annotation of 43BSDReno/contrib/emacs-18.55/src/sysdep.c, revision 1.1

1.1     ! root        1: /* Interfaces to system-dependent kernel and library entries.
        !             2:    Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU Emacs.
        !             5: 
        !             6: GNU Emacs is distributed in the hope that it will be useful,
        !             7: but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: accepts responsibility to anyone for the consequences of using it
        !             9: or for whether it serves any particular purpose or works at all,
        !            10: unless he says so in writing.  Refer to the GNU Emacs General Public
        !            11: License for full details.
        !            12: 
        !            13: Everyone is granted permission to copy, modify and redistribute
        !            14: GNU Emacs, but only under the conditions described in the
        !            15: GNU Emacs General Public License.   A copy of this license is
        !            16: supposed to have been given to you along with GNU Emacs so you
        !            17: can know your rights and responsibilities.  It should be in a
        !            18: file named COPYING.  Among other things, the copyright notice
        !            19: and this notice must be preserved on all copies.  */
        !            20: 
        !            21: 
        !            22: #include <signal.h>
        !            23: #include <setjmp.h>
        !            24: 
        !            25: #define USE_OLD_TTY
        !            26: 
        !            27: #include "config.h"
        !            28: #include "lisp.h"
        !            29: #undef NULL
        !            30: 
        !            31: #define min(x,y) ((x) > (y) ? (y) : (x))
        !            32: 
        !            33: /* In this file, open, read and write refer to the system calls,
        !            34:    not our sugared interfaces  sys_open, sys_read and sys_write.
        !            35:    Contrariwise, for systems where we use the system calls directly,
        !            36:    define sys_read, etc. here as aliases for them.  */
        !            37: #ifndef read
        !            38: #define sys_read read
        !            39: #define sys_write write
        !            40: #endif /* `read' is not a macro */
        !            41: 
        !            42: #undef read
        !            43: #undef write
        !            44: 
        !            45: #ifndef close
        !            46: #define sys_close close
        !            47: #else 
        !            48: #undef close
        !            49: #endif
        !            50: 
        !            51: #ifndef open
        !            52: #define sys_open open
        !            53: #else /* `open' is a macro */
        !            54: #undef open
        !            55: #endif /* `open' is a macro */
        !            56: 
        !            57: #include <stdio.h>
        !            58: #include <sys/types.h>
        !            59: #include <sys/stat.h>
        !            60: #include <errno.h>
        !            61: 
        !            62: extern int errno;
        !            63: #ifndef VMS
        !            64: extern char *sys_errlist[];
        !            65: #endif
        !            66: 
        !            67: #ifdef VMS
        !            68: #include <rms.h>
        !            69: #include <ttdef.h>
        !            70: #include <tt2def.h>
        !            71: #include <iodef.h>
        !            72: #include <ssdef.h>
        !            73: #include <descrip.h>
        !            74: #include <ctype.h>
        !            75: #include <file.h>
        !            76: #ifndef RAB$C_BID
        !            77: #include <rab.h>
        !            78: #endif
        !            79: #define        MAXIOSIZE ( 32 * PAGESIZE )     /* Don't I/O more than 32 blocks at a time */
        !            80: #endif /* VMS */
        !            81: 
        !            82: #ifndef BSD4_1
        !            83: #ifdef BSD /* this is done this way to avoid defined(BSD) || defined (USG)
        !            84:              because the vms compiler doesn't grok `defined' */
        !            85: #include <fcntl.h>
        !            86: #endif
        !            87: #ifdef USG
        !            88: #include <fcntl.h>
        !            89: #endif
        !            90: #endif /* not 4.1 bsd */
        !            91: 
        !            92: #ifdef BSD
        !            93: #include <sys/ioctl.h>
        !            94: #ifdef BSD4_1
        !            95: #include <wait.h>
        !            96: #else /* not 4.1 */
        !            97: #include <sys/wait.h>
        !            98: #endif /* not 4.1 */
        !            99: #endif /* BSD */
        !           100: 
        !           101: #ifdef STRIDE
        !           102: #include <sys/ioctl.h>
        !           103: #endif 
        !           104: 
        !           105: #ifdef mips
        !           106: #include <sys/ioctl.h>
        !           107: #endif 
        !           108: 
        !           109: /* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs.  */
        !           110: #ifdef BSD4_1
        !           111: #undef LLITOUT
        !           112: #define LLITOUT 0
        !           113: #endif /* 4.1 */
        !           114: 
        !           115: #ifdef HAVE_TERMIO
        !           116: #include <termio.h>
        !           117: #undef TIOCGETP
        !           118: #define TIOCGETP TCGETA
        !           119: #undef TIOCSETN
        !           120: #define TIOCSETN TCSETAW
        !           121: #undef TIOCSETP
        !           122: #define TIOCSETP TCSETAF
        !           123: #define TERMINAL struct termio
        !           124: #define OSPEED(str) (str.c_cflag & CBAUD)
        !           125: #define SETOSPEED(str,new) (str.c_cflag = (str.c_cflag & ~CBAUD) | (new))
        !           126: #define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3)
        !           127: #endif /* HAVE_TERMIO */
        !           128: 
        !           129: #ifdef XENIX
        !           130: #undef TIOCGETC  /* Avoid confusing some conditionals that test this.  */
        !           131: #endif
        !           132: 
        !           133: #ifndef HAVE_TERMIO
        !           134: #ifndef VMS
        !           135: #include <sgtty.h>
        !           136: #define TERMINAL struct sgttyb
        !           137: #define OSPEED(str) str.sg_ospeed
        !           138: #define SETOSPEED(str,new) (str.sg_ospeed = (new))
        !           139: #define TABS_OK(str) ((str.sg_flags & XTABS) != XTABS)
        !           140: #undef TCSETAW
        !           141: #define TCSETAW TIOCSETN
        !           142: #endif /* not VMS */
        !           143: #endif /* not HAVE_TERMIO */
        !           144: 
        !           145: #ifdef USG
        !           146: #include <sys/utsname.h>
        !           147: #include <memory.h>
        !           148: #include <string.h>
        !           149: #ifdef TIOCGWINSZ
        !           150: #ifndef IRIS_4D
        !           151: #ifndef mips
        !           152: /* Some USG systems with TIOCGWINSZ need this file; some don't have it.
        !           153:    We don't know how to distinguish them.
        !           154:    If this #include gets an error, just delete it.  */
        !           155: #include <sys/sioctl.h>
        !           156: #endif
        !           157: #endif
        !           158: #endif
        !           159: #ifdef HAVE_TIMEVAL
        !           160: #ifdef HPUX
        !           161: #include <time.h>
        !           162: #else
        !           163: #include <sys/time.h>
        !           164: #endif
        !           165: #endif /* HAVE_TIMEVAL */
        !           166: #endif /* USG */
        !           167: 
        !           168: #ifdef VMS
        !           169: #include "window.h"
        !           170: #endif
        !           171:   
        !           172: #ifdef NEED_BSDTTY
        !           173: #include <sys/bsdtty.h>
        !           174: #endif 
        !           175: 
        !           176: #include "termhooks.h"
        !           177: #include "termchar.h"
        !           178: #include "termopts.h"
        !           179: #include "dispextern.h"
        !           180: 
        !           181: #ifdef NONSYSTEM_DIR_LIBRARY
        !           182: #include "ndir.h"
        !           183: #endif /* NONSYSTEM_DIR_LIBRARY */
        !           184: 
        !           185: #ifndef sigmask
        !           186: #define sigmask(no) (1L << ((no) - 1))
        !           187: #endif
        !           188: 
        !           189: /* Define SIGCHLD as an alias for SIGCLD.  There are many conditionals
        !           190:    testing SIGCHLD.  */
        !           191: 
        !           192: #ifndef VMS
        !           193: #ifdef SIGCLD
        !           194: #ifndef SIGCHLD
        !           195: #define SIGCHLD SIGCLD
        !           196: #endif /* not SIGCHLD */
        !           197: #endif /* SIGCLD */
        !           198: #endif /* not VMS */
        !           199: 
        !           200: static int baud_convert[] =
        !           201: #ifdef BAUD_CONVERT
        !           202:   BAUD_CONVERT;
        !           203: #else
        !           204:   {
        !           205:     0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
        !           206:     1800, 2400, 4800, 9600, 19200, 38400
        !           207:   };
        !           208: #endif
        !           209: 
        !           210: extern short ospeed;
        !           211: 
        !           212: #ifdef VMS
        !           213: static struct iosb
        !           214: {
        !           215:   short status;
        !           216:   short offset;
        !           217:   short termlen;
        !           218:   short term;
        !           219: } input_iosb;
        !           220: 
        !           221: int kbd_input_ast ();
        !           222: 
        !           223: int waiting_for_ast;
        !           224: int stop_input;
        !           225: int input_ef = 0;
        !           226: int timer_ef = 0;
        !           227: int process_ef = 0;
        !           228: int input_eflist;
        !           229: int timer_eflist;
        !           230: 
        !           231: static int input_chan;
        !           232: static $DESCRIPTOR (input_dsc, "TT");
        !           233: static int terminator_mask[2] = { 0, 0 };
        !           234: 
        !           235: static struct sensemode {
        !           236:   short status;
        !           237:   unsigned char xmit_baud;
        !           238:   unsigned char rcv_baud;
        !           239:   unsigned char crfill;
        !           240:   unsigned char lffill;
        !           241:   unsigned char parity;
        !           242:   unsigned char unused;
        !           243:   char class;
        !           244:   char type;
        !           245:   short scr_wid;
        !           246:   unsigned long tt_char : 24, scr_len : 8;
        !           247:   unsigned long tt2_char;
        !           248: } sensemode_iosb;
        !           249: #define TERMINAL struct sensemode
        !           250: #define OSPEED(str) (str.xmit_baud)
        !           251: #define TABS_OK(str) ((str.tt_char & TT$M_MECHTAB) != 0)
        !           252: #endif /* VMS */
        !           253: 
        !           254: discard_tty_input ()
        !           255: {
        !           256:   TERMINAL buf;
        !           257: 
        !           258:   if (noninteractive)
        !           259:     return;
        !           260: 
        !           261: #ifdef VMS
        !           262:   end_kbd_input ();
        !           263:   SYS$QIOW (0, input_chan, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
        !           264:            &buf, 0, 0, terminator_mask, 0, 0);
        !           265:   queue_kbd_input ();
        !           266: #else /* not VMS */
        !           267:   ioctl (0, TIOCGETP, &buf);
        !           268:   ioctl (0, TIOCSETP, &buf);
        !           269: #endif /* not VMS */
        !           270: }
        !           271: 
        !           272: #ifdef SIGTSTP
        !           273: 
        !           274: stuff_char (c)
        !           275:      char c;
        !           276: {
        !           277: /* Should perhaps error if in batch mode */
        !           278: #ifdef TIOCSTI
        !           279:   ioctl (0, TIOCSTI, &c);
        !           280: #else /* no TIOCSTI */
        !           281:   error ("Cannot stuff terminal input characters in this version of Unix.");
        !           282: #endif /* no TIOCSTI */
        !           283: }
        !           284: 
        !           285: #endif /* SIGTSTP */
        !           286: 
        !           287: init_baud_rate ()
        !           288: {
        !           289:   TERMINAL sg;
        !           290: 
        !           291:   if (noninteractive)
        !           292:     ospeed = 0;
        !           293:   else
        !           294:     {
        !           295: #ifdef VMS
        !           296:       SYS$QIOW (0, input_chan, IO$_SENSEMODE, &sg, 0, 0,
        !           297:                &sg.class, 12, 0, 0, 0, 0 );
        !           298: #else
        !           299:       SETOSPEED (sg, B9600);
        !           300:       ioctl (0, TIOCGETP, &sg);
        !           301: #endif /* not VMS */
        !           302:       ospeed = OSPEED (sg);
        !           303:     }
        !           304:   baud_rate = ospeed == 0 ? 1200
        !           305:     : ospeed < sizeof baud_convert / sizeof baud_convert[0]
        !           306:       ? baud_convert[ospeed] : 9600;
        !           307: }
        !           308: 
        !           309: /*ARGSUSED*/
        !           310: set_exclusive_use (fd)
        !           311:      int fd;
        !           312: {
        !           313: #ifdef FIOCLEX
        !           314:   ioctl (fd, FIOCLEX, 0);
        !           315: #endif
        !           316:   /* Ok to do nothing if this feature does not exist */
        !           317: }
        !           318: 
        !           319: #ifndef subprocesses
        !           320: 
        !           321: wait_without_blocking ()
        !           322: {
        !           323: #ifdef BSD
        !           324:   wait3 (0, WNOHANG | WUNTRACED, 0);
        !           325: #else
        !           326:   croak ("wait_without_blocking");
        !           327: #endif
        !           328: }
        !           329: 
        !           330: #endif /* not subprocesses */
        !           331: 
        !           332: int wait_debugging;   /* Set nonzero to make following function work under dbx
        !           333:                         (at least for bsd).  */
        !           334: 
        !           335: /* Wait for subprocess with process id `pid' to terminate and
        !           336:    make sure it will get eliminated (not remain forever as a zombie) */
        !           337: 
        !           338: wait_for_termination (pid)
        !           339:      int pid;
        !           340: {
        !           341:   while (1)
        !           342:     {
        !           343: #ifdef subprocesses
        !           344: #if defined(BSD) || (defined(HPUX) && !defined(HPUX_5))
        !           345:       /* Note that kill returns -1 even if the process is just a zombie now.
        !           346:         But inevitably a SIGCHLD interrupt should be generated
        !           347:         and child_sig will do wait3 and make the process go away. */
        !           348:       /* There is some indication that there is a bug involved with
        !           349:         termination of subprocesses, perhaps involving a kernel bug too,
        !           350:         but no idea what it is.  Just as a hunch we signal SIGCHLD to see
        !           351:         if that causes the problem to go away or get worse.  */
        !           352: #ifdef BSD4_1
        !           353:       extern int synch_process_pid;
        !           354:       sighold (SIGCHLD);
        !           355:       if (synch_process_pid == 0)
        !           356:        {
        !           357:           sigrelse (SIGCHLD);
        !           358:          break;
        !           359:        }
        !           360:       if (wait_debugging)
        !           361:        sleep (1);
        !           362:       else
        !           363:        sigpause (SIGCHLD);
        !           364: #else /* not BSD4_1 */
        !           365:       sigsetmask (1 << (SIGCHLD - 1));
        !           366:       if (0 > kill (pid, 0))
        !           367:         {
        !           368:          sigsetmask (0);
        !           369:          kill (getpid (), SIGCHLD);
        !           370:          break;
        !           371:        }
        !           372:       if (wait_debugging)
        !           373:        sleep (1);
        !           374:       else
        !           375:        sigpause (0);
        !           376: #endif /* not BSD4_1 */
        !           377: #else /* not BSD, and not HPUX version >= 6 */
        !           378: #ifdef UNIPLUS
        !           379:       if (0 > kill (pid, 0))
        !           380:        break;
        !           381:       wait (0);
        !           382: #else /* neither BSD nor UNIPLUS: random sysV */
        !           383:       if (0 > kill (pid, 0))
        !           384:        break;
        !           385:       pause ();
        !           386: #endif /* not UNIPLUS */
        !           387: #endif /* not BSD, and not HPUX version >= 6 */
        !           388: #else /* not subprocesses */
        !           389: #ifndef BSD4_1
        !           390:       if (0 > kill (pid, 0))
        !           391:        break;
        !           392:       wait (0);
        !           393: #else /* BSD4_1 */
        !           394:       int status;
        !           395:       status = wait (0);
        !           396:       if (status == pid || status == -1)
        !           397:        break;
        !           398: #endif /* BSD4_1 */
        !           399: #endif /* not subprocesses */
        !           400:     }
        !           401: }
        !           402: 
        !           403: #ifdef subprocesses
        !           404: 
        !           405: /*
        !           406:  *     flush any pending output
        !           407:  *      (may flush input as well; it does not matter the way we use it)
        !           408:  */
        !           409:  
        !           410: flush_pending_output (channel)
        !           411:      int channel;
        !           412: {
        !           413: #ifdef TCFLSH
        !           414:   ioctl (channel, TCFLSH, 1);
        !           415: #else
        !           416: #ifdef TIOCFLUSH
        !           417:   int zero = 0;
        !           418:   /* 3rd arg should be ignored
        !           419:      but some 4.2 kernels actually want the address of an int
        !           420:      and nonzero means something different.  */
        !           421:   ioctl (channel, TIOCFLUSH, &zero);
        !           422: #endif
        !           423: #endif
        !           424: }
        !           425: 
        !           426: /*  Set up the terminal at the other end of a pseudo-terminal that
        !           427:     we will be controlling an inferior through.
        !           428:     It should not echo or do line-editing, since that is done
        !           429:     in Emacs.  No padding needed for insertion into an Emacs buffer.  */
        !           430: 
        !           431: child_setup_tty (out)
        !           432:      int out;
        !           433: {
        !           434:   TERMINAL s;
        !           435: 
        !           436:   ioctl (out, TIOCGETP, &s);
        !           437: #ifdef HAVE_TERMIO
        !           438:   s.c_oflag |= OPOST;          /* Enable output postprocessing */
        !           439:   s.c_oflag &= ~ONLCR;         /* Disable map of NL to CR-NL on output */
        !           440:   s.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);        /* No output delays */
        !           441:   s.c_lflag &= ~ECHO;          /* Disable echo */
        !           442:   s.c_lflag |= ISIG;           /* Enable signals */
        !           443:   s.c_iflag &= ~IUCLC;         /* Disable map of upper case to lower on input */
        !           444:   s.c_oflag &= ~OLCUC;         /* Disable map of lower case to upper on output */
        !           445: /* said to be unnecesary
        !           446:   s.c_cc[VMIN] = 1;            /* minimum number of characters to accept
        !           447:   s.c_cc[VTIME] = 0;           /* wait forever for at least 1 character
        !           448: */
        !           449:   s.c_lflag |= ICANON;         /* Enable erase/kill and eof processing */
        !           450:   s.c_cc[VEOF] = 04;           /* insure that EOF is Control-D */
        !           451:   s.c_cc[VERASE] = 0377;       /* disable erase processing */
        !           452:   s.c_cc[VKILL] = 0377;                /* disable kill processing */
        !           453: #ifdef HPUX
        !           454:   s.c_cflag = (s.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
        !           455: #endif HPUX
        !           456: #ifdef IBMRTAIX
        !           457: /* AIX enhanced edit loses NULs, so disable it */
        !           458:   s.c_line = 0;
        !           459:   s.c_iflag &= ~ASCEDIT;
        !           460:   /* Also, PTY overloads NUL and BREAK.
        !           461:      don't ignore break, but don't signal either, so it looks like NUL.  */
        !           462:   s.c_iflag &= ~IGNBRK;
        !           463:   s.c_iflag &= ~BRKINT;
        !           464: /* QUIT and INTR work better as signals, so disable character forms */
        !           465:   s.c_cc[VQUIT] = 0377;
        !           466:   s.c_cc[VINTR] = 0377;
        !           467:   s.c_cc[VEOL] = 0377;
        !           468:   s.c_lflag &= ~ISIG;
        !           469:   s.c_cflag = (s.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
        !           470: #endif /* IBMRTAIX */
        !           471: 
        !           472: #else /* not HAVE_TERMIO */
        !           473:   s.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE | CBREAK | TANDEM);
        !           474: #endif /* not HAVE_TERMIO */
        !           475: 
        !           476:   ioctl (out, TIOCSETN, &s);
        !           477: 
        !           478: #ifdef BSD4_1
        !           479:   if (interrupt_input)
        !           480:     reset_sigio ();
        !           481: #endif /* BSD4_1 */
        !           482: #ifdef RTU
        !           483:   {
        !           484:     int zero = 0;
        !           485:     ioctl (out, FIOASYNC, &zero);
        !           486:   }
        !           487: #endif /* RTU */
        !           488: }
        !           489: 
        !           490: #endif /* subprocesses */
        !           491: 
        !           492: /*ARGSUSED*/
        !           493: setpgrp_of_tty (pid)
        !           494:      int pid;
        !           495: {
        !           496: #ifdef TIOCSPGRP
        !           497:   ioctl (0, TIOCSPGRP, &pid);
        !           498: #else
        !           499:   /* Just ignore this for now and hope for the best */
        !           500: #endif
        !           501: }
        !           502: 
        !           503: /* Suspend the Emacs process; give terminal to its superior.  */
        !           504: 
        !           505: sys_suspend ()
        !           506: {
        !           507: #ifdef VMS
        !           508:   unsigned long parent_id;
        !           509: 
        !           510:   parent_id = getppid ();
        !           511:   if (parent_id && parent_id != 0xffffffff)
        !           512:     {
        !           513:       int oldsig = signal (SIGINT, SIG_IGN);
        !           514:       int status = LIB$ATTACH (&parent_id) & 1;
        !           515:       signal (SIGINT, oldsig);
        !           516:       return status;
        !           517:     }
        !           518:   return -1;
        !           519: #else
        !           520: #ifdef SIGTSTP
        !           521: #ifdef BSD
        !           522:   killpg (getpgrp (0), SIGTSTP);
        !           523: #else
        !           524:   kill (-getpgrp (0), SIGTSTP);
        !           525: #endif
        !           526: 
        !           527: #else
        !           528: #ifdef USG_JOBCTRL /* If you don't know what this is don't mess with it */
        !           529:   ptrace (0, 0, 0, 0);         /* set for ptrace - caught by csh */
        !           530:   kill (getpid (), SIGQUIT);
        !           531: 
        !           532: #else
        !           533: 
        !           534: /* On a system where suspending is not implemented,
        !           535:    instead fork a subshell and let it talk directly to the terminal
        !           536:    while we wait.  */
        !           537:   int pid = fork ();
        !           538:   int (*interrupt) ();
        !           539:   int (*quit) ();
        !           540:   int (*term) ();
        !           541: #ifdef SIGIO
        !           542:   int (*sigio) ();
        !           543: #endif SIGIO
        !           544: 
        !           545:   if (pid == -1)
        !           546:     error ("Can't spawn subshell");
        !           547:   if (pid == 0)
        !           548:     {
        !           549:       char *sh;
        !           550: 
        !           551:       sh = (char *) egetenv ("SHELL");
        !           552:       if (sh == 0)
        !           553:        sh = "sh";
        !           554:       /* Use our buffer's default directory for the subshell.  */
        !           555:       {
        !           556:        Lisp_Object dir;
        !           557:        unsigned char *str;
        !           558:        int len;
        !           559: 
        !           560:        /* mentioning bf_cur->buffer would mean including buffer.h,
        !           561:           which somehow wedges the hp compiler.  So instead... */
        !           562: 
        !           563:        dir = intern ("default-directory");
        !           564:        /* Can't use NULL */
        !           565:        if (XFASTINT (Fboundp (dir)) == XFASTINT (Qnil))
        !           566:          goto xyzzy;
        !           567:        dir = Fsymbol_value (dir);
        !           568:        if (XTYPE (dir) != Lisp_String)
        !           569:          goto xyzzy;
        !           570: 
        !           571:        str = (unsigned char *) alloca (XSTRING (dir)->size + 2);
        !           572:        len = XSTRING (dir)->size;
        !           573:        bcopy (XSTRING (dir)->data, str, len);
        !           574:        if (str[len - 1] != '/') str[len++] = '/';
        !           575:        str[len] = 0;
        !           576:        chdir (str);
        !           577:       }
        !           578:     xyzzy:
        !           579: #ifdef subprocesses
        !           580:       close_process_descs ();  /* Close Emacs's pipes/ptys */
        !           581: #endif
        !           582:       execlp (sh, sh, 0);
        !           583:       write (1, "Can't execute subshell", 22);
        !           584:       _exit (1);
        !           585:     }
        !           586:   interrupt = (int (*)()) signal (SIGINT, SIG_IGN);
        !           587:   quit = (int (*)()) signal (SIGQUIT, SIG_IGN);
        !           588:   term = (int (*)()) signal (SIGTERM, SIG_IGN);
        !           589: #ifdef SIGIO
        !           590:   sigio = (int (*)()) signal (SIGIO, SIG_IGN);
        !           591: #endif /* SIGIO */
        !           592:   wait_for_termination (pid);
        !           593:   signal (SIGINT, interrupt);
        !           594:   signal (SIGQUIT, quit);
        !           595:   signal (SIGTERM, term);
        !           596: #ifdef SIGIO
        !           597:   signal (SIGIO, sigio);
        !           598: #endif /* SIGIO */
        !           599: #endif /* no USG_JOBCTRL */
        !           600: #endif /* no SIGTSTP */
        !           601: #endif /* not VMS */
        !           602: }
        !           603: 
        !           604: #ifdef F_SETFL
        !           605: 
        !           606: int old_fcntl_flags;
        !           607: 
        !           608: init_sigio ()
        !           609: {
        !           610: #ifdef FASYNC
        !           611:   old_fcntl_flags = fcntl (0, F_GETFL, 0) & ~FASYNC;
        !           612: #endif
        !           613:   request_sigio ();
        !           614: }
        !           615: 
        !           616: reset_sigio ()
        !           617: {
        !           618:   unrequest_sigio ();
        !           619: }
        !           620: 
        !           621: #ifdef FASYNC          /* F_SETFL does not imply existance of FASYNC */
        !           622: 
        !           623: request_sigio ()
        !           624: {
        !           625: #ifdef SIGWINCH
        !           626:   int omask = sigblock (0);
        !           627:   sigsetmask (omask & ~sigmask (SIGWINCH));
        !           628: #endif
        !           629:   fcntl (0, F_SETFL, old_fcntl_flags | FASYNC);
        !           630: 
        !           631:   interrupts_deferred = 0;
        !           632: }
        !           633: 
        !           634: unrequest_sigio ()
        !           635: {
        !           636: #ifdef SIGWINCH
        !           637:   sigblock (sigmask (SIGWINCH));
        !           638: #endif
        !           639:   fcntl (0, F_SETFL, old_fcntl_flags);
        !           640:   interrupts_deferred = 1;
        !           641: }
        !           642: 
        !           643: #else /* no FASYNC */
        !           644: #ifdef STRIDE          /* Stride doesn't have FASYNC - use FIOASYNC */
        !           645: 
        !           646: request_sigio ()
        !           647: {
        !           648:   int on = 1;
        !           649:   ioctl (0, FIOASYNC, &on);
        !           650:   interrupts_deferred = 0;
        !           651: }
        !           652: 
        !           653: unrequest_sigio ()
        !           654: {
        !           655:   int off = 0;
        !           656: 
        !           657:   ioctl (0, FIOASYNC, &off);
        !           658:   interrupts_deferred = 1;
        !           659: }
        !           660: 
        !           661: #else /* not FASYNC, not STRIDE */
        !           662:  
        !           663: request_sigio ()
        !           664: {
        !           665:   croak ("request_sigio");
        !           666: }
        !           667:  
        !           668: unrequest_sigio ()
        !           669: {
        !           670:   croak ("unrequest_sigio");
        !           671: }
        !           672:  
        !           673: #endif /* STRIDE */
        !           674: #endif /* FASYNC */
        !           675: #endif /* F_SETFL */
        !           676: 
        !           677: TERMINAL old_gtty;             /* The initial tty mode bits */
        !           678: 
        !           679: int term_initted;              /* 1 if outer tty status has been recorded */
        !           680: 
        !           681: #ifdef F_SETOWN
        !           682: int old_fcntl_owner;
        !           683: #endif /* F_SETOWN */
        !           684: 
        !           685: #ifdef TIOCGLTC
        !           686: struct ltchars old_ltchars;
        !           687: #endif /* TIOCGLTC */
        !           688: 
        !           689: #ifdef TIOCGETC
        !           690: struct tchars old_tchars;
        !           691: int old_lmode;
        !           692: 
        !           693: int lmode;                     /* Current lmode value. */
        !           694:                                /* Needed as global for 4.1 */
        !           695: #endif /* TIOCGETC */
        !           696: 
        !           697: /* This may also be defined in stdio,
        !           698:    but if so, this does no harm,
        !           699:    and using the same name avoids wasting the other one's space.  */
        !           700: 
        !           701: #ifdef USG
        !           702: unsigned char _sobuf[BUFSIZ+8];
        !           703: #else
        !           704: char _sobuf[BUFSIZ];
        !           705: #endif
        !           706:  
        !           707: #ifdef TIOCGLTC
        !           708: static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
        !           709: #endif
        !           710: #ifdef TIOCGETC
        !           711:   static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
        !           712: #endif 
        !           713: 
        !           714: init_sys_modes ()
        !           715: {
        !           716:   TERMINAL sg;
        !           717: #ifdef TIOCGETC
        !           718:   struct tchars tchars;
        !           719: #endif
        !           720: #ifdef VMS
        !           721: #if 0
        !           722:   static int oob_chars[2] = {0, 1 << 7}; /* catch C-g's */
        !           723:   extern int (*interrupt_signal) ();
        !           724: #endif
        !           725: #endif
        !           726: 
        !           727:   if (noninteractive)
        !           728:     return;
        !           729: 
        !           730: #ifdef VMS
        !           731:   if (!input_ef)
        !           732:     LIB$GET_EF (&input_ef);
        !           733:   SYS$CLREF (input_ef);
        !           734:   waiting_for_ast = 0;
        !           735:   if (!timer_ef)
        !           736:     LIB$GET_EF (&timer_ef);
        !           737:   SYS$CLREF (timer_ef);
        !           738:   if (!process_ef)
        !           739:     LIB$GET_EF (&process_ef);
        !           740:   SYS$CLREF (process_ef);
        !           741:   if (input_ef / 32 != process_ef / 32)
        !           742:     croak ("Input and process event flags in different clusters.");
        !           743:   if (input_ef / 32 != timer_ef / 32)
        !           744:     croak ("Input and process event flags in different clusters.");
        !           745:   input_eflist = ((unsigned) 1 << (input_ef % 32)) |
        !           746:     ((unsigned) 1 << (process_ef % 32));
        !           747:   timer_eflist = ((unsigned) 1 << (input_ef % 32)) |
        !           748:     ((unsigned) 1 << (timer_ef % 32));
        !           749:   SYS$QIOW (0, input_chan, IO$_SENSEMODE, &old_gtty, 0, 0,
        !           750:            &old_gtty.class, 12, 0, 0, 0, 0);
        !           751: #ifndef VMS4_4
        !           752:   sys_access_reinit ();
        !           753: #endif
        !           754: #else /* not VMS */
        !           755:   ioctl (0, TIOCGETP, &old_gtty);
        !           756: #endif /* not VMS */
        !           757:   if (!read_socket_hook)
        !           758:     {
        !           759:       sg = old_gtty;
        !           760: 
        !           761: #ifdef HAVE_TERMIO
        !           762:       sg.c_iflag |= (IGNBRK);  /* Ignore break condition */
        !           763:       sg.c_iflag &= ~ICRNL;    /* Disable map of CR to NL on input */
        !           764: #ifdef ISTRIP
        !           765:       sg.c_iflag &= ~ISTRIP;   /* don't strip 8th bit on input */
        !           766: #endif
        !           767:       sg.c_lflag &= ~ECHO;     /* Disable echo */
        !           768:       sg.c_lflag &= ~ICANON;   /* Disable erase/kill processing */
        !           769:       sg.c_lflag |= ISIG;      /* Enable signals */
        !           770:       if (flow_control)
        !           771:        {
        !           772:          sg.c_iflag |= IXON;   /* Enable start/stop output control */
        !           773: #ifdef IXANY
        !           774:          sg.c_iflag &= ~IXANY;
        !           775: #endif /* IXANY */
        !           776:        }
        !           777:       else
        !           778:        sg.c_iflag &= ~IXON;    /* Disable start/stop output control */
        !           779:       sg.c_oflag &= ~ONLCR;    /* Disable map of NL to CR-NL on output */
        !           780:       sg.c_oflag &= ~TAB3;     /* Disable tab expansion */
        !           781: #ifdef CS8
        !           782:       sg.c_cflag |= CS8;       /* allow 8th bit on input */
        !           783:       sg.c_cflag &= ~PARENB;   /* Don't check parity */
        !           784: #endif
        !           785:       sg.c_cc[VINTR] = '\007'; /* ^G gives SIGINT */
        !           786:       /* Set up C-g for both SIGQUIT and SIGINT.
        !           787:         We don't know which we will get, but we handle both alike
        !           788:         so which one it really gives us does not matter.  */
        !           789:       sg.c_cc[VQUIT] = '\007';
        !           790:       sg.c_cc[VMIN] = 1;       /* Input should wait for at least 1 char */
        !           791:       sg.c_cc[VTIME] = 0;      /* no matter how long that takes.  */
        !           792: #ifdef VSWTCH
        !           793:       sg.c_cc[VSWTCH] = CDEL;  /* Turn off shell layering use of C-z */
        !           794: #endif /* VSWTCH */
        !           795: #ifdef IBMRTAIX
        !           796:       /* AIX enhanced edit loses NULs, so disable it */
        !           797:       sg.c_line = 0;
        !           798:       sg.c_iflag &= ~ASCEDIT;
        !           799:       /* Also, PTY overloads NUL and BREAK.
        !           800:         don't ignore break, but don't signal either, so it looks like NUL.
        !           801:         This really serves a purpose only if running in an XTERM window
        !           802:         or via TELNET or the like, but does no harm elsewhere.  */
        !           803:       sg.c_iflag &= ~IGNBRK;
        !           804:       sg.c_iflag &= ~BRKINT;
        !           805: #endif
        !           806: #else /* if not HAVE_TERMIO */
        !           807: #ifdef VMS
        !           808:       sg.tt_char |= TT$M_NOECHO | TT$M_EIGHTBIT;
        !           809:       if (flow_control)
        !           810:        sg.tt_char |= TT$M_TTSYNC;
        !           811:       else
        !           812:        sg.tt_char &= ~TT$M_TTSYNC;
        !           813:       sg.tt2_char |= TT2$M_PASTHRU | TT2$M_XON;
        !           814: #else /* not VMS (BSD, that is) */
        !           815:       sg.sg_flags &= ~(ECHO | CRMOD | XTABS);
        !           816:       sg.sg_flags |= ANYP;
        !           817:       sg.sg_flags |= interrupt_input ? RAW : CBREAK;
        !           818: #endif /* not VMS (BSD, that is) */
        !           819: #endif /* not HAVE_TERMIO */
        !           820: 
        !           821: #ifdef VMS
        !           822:       SYS$QIOW (0, input_chan, IO$_SETMODE, &input_iosb, 0, 0,
        !           823:                &sg.class, 12, 0, 0, 0, 0);
        !           824: #else
        !           825:       ioctl (0, TIOCSETN, &sg);
        !           826: #endif /* not VMS */
        !           827: 
        !           828:       /* This code added to insure that, if flow-control is not to be used,
        !           829:         we have an unlocked screen at the start. */
        !           830: #ifdef TCXONC
        !           831:       if (!flow_control) ioctl (0, TCXONC, 1);
        !           832: #endif
        !           833: #ifdef TIOCSTART
        !           834:       if (!flow_control) ioctl (0, TIOCSTART, 0);
        !           835: #endif
        !           836: 
        !           837: #ifdef AIX
        !           838:       hft_init ();
        !           839: #endif
        !           840: 
        !           841: #ifdef F_SETFL
        !           842: #ifdef F_GETOWN                /* F_SETFL does not imply existance of F_GETOWN */
        !           843:       if (interrupt_input)
        !           844:        {
        !           845:          old_fcntl_owner = fcntl (0, F_GETOWN, 0);
        !           846:          fcntl (0, F_SETOWN, getpid ());
        !           847:          init_sigio ();
        !           848:        }
        !           849: #endif /* F_GETOWN */
        !           850: #endif /* F_SETFL */
        !           851: 
        !           852:       /* If going to use CBREAK mode, we must request C-g to interrupt
        !           853:           and turn off start and stop chars, etc.
        !           854:           If not going to use CBREAK mode, do this anyway
        !           855:           so as to turn off local flow control for user coming over
        !           856:           network on 4.2; in this case, only t_stopc and t_startc really matter.  */
        !           857: #ifdef TIOCGLTC
        !           858:       ioctl (0, TIOCGLTC, &old_ltchars);
        !           859: #endif /* TIOCGLTC */
        !           860: #ifndef HAVE_TERMIO
        !           861: #ifdef TIOCGETC
        !           862:       ioctl (0, TIOCGETC, &old_tchars);
        !           863:       ioctl (0, TIOCLGET, &old_lmode);
        !           864: 
        !           865:       /* Note: if not using CBREAK mode, it makes no difference how we set this */
        !           866:       tchars = new_tchars;
        !           867:       tchars.t_intrc = 07;
        !           868:       if (flow_control)
        !           869:        {
        !           870:          tchars.t_startc = '\021';
        !           871:          tchars.t_stopc = '\023';
        !           872:        }
        !           873: /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
        !           874: #ifndef LPASS8
        !           875: #define LPASS8 0
        !           876: #endif
        !           877: 
        !           878: #ifdef BSD4_1
        !           879: #define LNOFLSH 0100000
        !           880: #endif
        !           881: 
        !           882:       lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_lmode;
        !           883: 
        !           884:       ioctl (0, TIOCSETC, &tchars);
        !           885:       ioctl (0, TIOCLSET, &lmode);
        !           886: #endif /* TIOCGETC */
        !           887: #endif /* not HAVE_TERMIO */
        !           888: #ifdef TIOCGLTC
        !           889:       ioctl (0, TIOCSLTC, &new_ltchars);
        !           890: #endif /* TIOCGLTC */
        !           891: 
        !           892: #ifdef BSD4_1
        !           893:       if (interrupt_input)
        !           894:        init_sigio ();
        !           895: #endif
        !           896: #ifdef VMS
        !           897: /*  Appears to do nothing when in PASTHRU mode.
        !           898:       SYS$QIOW (0, input_chan, IO$_SETMODE|IO$M_OUTBAND, 0, 0, 0,
        !           899:                interrupt_signal, oob_chars, 0, 0, 0, 0);
        !           900: */
        !           901:       queue_kbd_input (0);
        !           902: #endif /* VMS */
        !           903:     }
        !           904: #ifdef VMS  /* VMS sometimes has this symbol but lacks setvbuf.  */
        !           905: #undef _IOFBF
        !           906: #endif
        !           907: #ifdef _IOFBF
        !           908:   /* This symbol is defined on recent USG systems.
        !           909:      Someone says without this call USG won't really buffer the file
        !           910:      even with a call to setbuf(). */
        !           911:   setvbuf (stdout, _sobuf, _IOFBF, sizeof _sobuf);
        !           912: #else
        !           913:   setbuf (stdout, _sobuf);
        !           914: #endif
        !           915:   set_terminal_modes ();
        !           916:   if (term_initted && no_redraw_on_reenter)
        !           917:     {
        !           918:       if (display_completed)
        !           919:        direct_output_forward_char (0);
        !           920:     }
        !           921:   else
        !           922:     screen_garbaged = 1;
        !           923:   term_initted = 1;
        !           924: }
        !           925: 
        !           926: /* Return nonzero if safe to use tabs in output.
        !           927:    At the time this is called, init_sys_modes has not been done yet.  */
        !           928:    
        !           929: tabs_safe_p ()
        !           930: {
        !           931:   TERMINAL sg;
        !           932:   if (noninteractive)
        !           933:     return 1;
        !           934: #ifdef VMS
        !           935:   SYS$QIOW (0, input_chan, IO$_SENSEMODE, &sg, 0, 0,
        !           936:            &sg.class, 12, 0, 0, 0, 0);
        !           937: #else
        !           938:   ioctl (0, TIOCGETP, &sg);
        !           939: #endif /* not VMS */
        !           940:   return (TABS_OK(sg));
        !           941: }
        !           942: 
        !           943: /* Get terminal size from system.
        !           944:    Store number of lines into *heightp and width into *widthp.
        !           945:    If zero or a negative number is stored, the value is not valid.  */
        !           946: 
        !           947: get_screen_size (widthp, heightp)
        !           948:      int *widthp, *heightp;
        !           949: {
        !           950: /* Define the 4.3 names in terms of the Sun names
        !           951:    if the latter exist and the former do not.  */
        !           952: #ifdef TIOCGSIZE
        !           953: #ifndef TIOCGWINSZ
        !           954: #define TIOCGWINSZ TIOCGSIZE
        !           955: #define winsize ttysize
        !           956: #define ws_row ts_lines
        !           957: #define ws_col ts_cols
        !           958: #endif
        !           959: #endif /* Sun */
        !           960: 
        !           961: /* Do it using the 4.3 names if possible.  */
        !           962: #ifdef TIOCGWINSZ
        !           963:   struct winsize size;
        !           964:   *widthp = 0;
        !           965:   *heightp = 0;
        !           966:   if (ioctl (0, TIOCGWINSZ, &size) < 0)
        !           967:     return;
        !           968:   if ((unsigned) size.ws_col > MScreenWidth
        !           969:       || (unsigned) size.ws_row > MScreenLength)
        !           970:     return;
        !           971:   *widthp = size.ws_col;
        !           972:   *heightp = size.ws_row;
        !           973: #else /* not TIOCGWNSIZ */
        !           974: #ifdef VMS
        !           975:   TERMINAL sg;
        !           976:   SYS$QIOW (0, input_chan, IO$_SENSEMODE, &sg, 0, 0,
        !           977:            &sg.class, 12, 0, 0, 0, 0);
        !           978:   *widthp = sg.scr_wid;
        !           979:   *heightp = sg.scr_len;
        !           980: #else /* system doesn't know size */
        !           981:   *widthp = 0;
        !           982:   *heightp = 0;
        !           983: #endif /* system does not know size */
        !           984: #endif /* not TIOCGWINSZ */
        !           985: }
        !           986: 
        !           987: reset_sys_modes ()
        !           988: {
        !           989:   if (noninteractive)
        !           990:     {
        !           991:       fflush (stdout);
        !           992:       return;
        !           993:     }
        !           994:   if (!term_initted)
        !           995:     return;
        !           996:   if (read_socket_hook)
        !           997:     return;
        !           998:   topos (screen_height - 1, 0);
        !           999:   clear_end_of_line (screen_width);
        !          1000:   /* clear_end_of_line may move the cursor */
        !          1001:   topos (screen_height - 1, 0);
        !          1002:   /* Output raw CR so kernel can track the cursor hpos.  */
        !          1003:   cmputc ('\r');
        !          1004:   reset_terminal_modes ();
        !          1005:   fflush (stdout);
        !          1006: #ifdef BSD
        !          1007: #ifndef BSD4_1
        !          1008:   /* Avoid possible loss of output when changing terminal modes.  */
        !          1009:   fsync (fileno (stdout));
        !          1010: #endif
        !          1011: #endif
        !          1012: #ifdef TIOCGLTC
        !          1013:   ioctl (0, TIOCSLTC, &old_ltchars);
        !          1014: #endif /* TIOCGLTC */
        !          1015: #ifndef HAVE_TERMIO
        !          1016: #ifdef TIOCGETC
        !          1017:   ioctl (0, TIOCSETC, &old_tchars);
        !          1018:   ioctl (0, TIOCLSET, &old_lmode);
        !          1019: #endif /* TIOCGETC */
        !          1020: #endif /* not HAVE_TERMIO */
        !          1021: #ifdef F_SETFL
        !          1022: #ifdef F_SETOWN                /* F_SETFL does not imply existance of F_SETOWN */
        !          1023:   if (interrupt_input)
        !          1024:     {
        !          1025:       reset_sigio ();
        !          1026:       fcntl (0, F_SETOWN, old_fcntl_owner);
        !          1027:     }
        !          1028: #endif /* F_SETOWN */
        !          1029: #endif /* F_SETFL */
        !          1030: #ifdef BSD4_1
        !          1031:   if (interrupt_input)
        !          1032:     reset_sigio ();
        !          1033: #endif /* BSD4_1 */
        !          1034: #ifdef VMS
        !          1035:   end_kbd_input ();
        !          1036:   SYS$QIOW (0, input_chan, IO$_SETMODE, &input_iosb, 0, 0,
        !          1037:            &old_gtty.class, 12, 0, 0, 0, 0);
        !          1038: #else /* not VMS */
        !          1039:   while (ioctl (0, TCSETAW, &old_gtty) < 0 && errno == EINTR);
        !          1040: #endif /* not VMS */
        !          1041: 
        !          1042: #ifdef AIX
        !          1043:   hft_reset ();
        !          1044: #endif
        !          1045: }
        !          1046: 
        !          1047: #ifdef VMS
        !          1048: 
        !          1049: /* Assigning an input channel is done at the start of Emacs execution.
        !          1050:    This is called each time Emacs is resumed, also, but does nothing
        !          1051:    because input_chain is no longer zero.  */
        !          1052: 
        !          1053: init_vms_input()
        !          1054: {
        !          1055:   int status;
        !          1056:   
        !          1057:   if (input_chan == 0)
        !          1058:     {
        !          1059:       status = SYS$ASSIGN (&input_dsc, &input_chan, 0, 0);
        !          1060:       if (! (status & 1))
        !          1061:        LIB$STOP (status);
        !          1062:     }
        !          1063: }
        !          1064: 
        !          1065: /* Deassigning the input channel is done before exiting.  */
        !          1066: 
        !          1067: stop_vms_input ()
        !          1068: {
        !          1069:   return SYS$DASSGN (input_chan);
        !          1070: }
        !          1071: 
        !          1072: short input_buffer;
        !          1073: 
        !          1074: /* Request reading one character into the keyboard buffer.
        !          1075:    This is done as soon as the buffer becomes empty.  */
        !          1076: 
        !          1077: queue_kbd_input ()
        !          1078: {
        !          1079:   int status;
        !          1080:   waiting_for_ast = 0;
        !          1081:   stop_input = 0;
        !          1082:   status = SYS$QIO (0, input_chan, IO$_READVBLK,
        !          1083:                    &input_iosb, kbd_input_ast, 1,
        !          1084:                    &input_buffer, 1, 0, terminator_mask, 0, 0);
        !          1085: }
        !          1086: 
        !          1087: int input_count;
        !          1088: 
        !          1089: /* Ast routine that is called when keyboard input comes in
        !          1090:    in accord with the SYS$QIO above.  */
        !          1091: 
        !          1092: kbd_input_ast ()
        !          1093: {
        !          1094:   register int c = -1;
        !          1095:   int old_errno = errno;
        !          1096: 
        !          1097:   if (waiting_for_ast)
        !          1098:     SYS$SETEF (input_ef);
        !          1099:   waiting_for_ast = 0;
        !          1100:   input_count++;
        !          1101: #ifdef ASTDEBUG
        !          1102:   if (input_count == 25)
        !          1103:     exit (1);
        !          1104:   printf ("Ast # %d,", input_count);
        !          1105:   printf (" iosb = %x, %x, %x, %x",
        !          1106:          input_iosb.offset, input_iosb.status, input_iosb.termlen,
        !          1107:          input_iosb.term);
        !          1108: #endif
        !          1109:   if (input_iosb.offset)
        !          1110:     {
        !          1111:       c = input_buffer;
        !          1112: #ifdef ASTDEBUG
        !          1113:       printf (", char = 0%o", c);
        !          1114: #endif
        !          1115:     }
        !          1116: #ifdef ASTDEBUG
        !          1117:   printf ("\n");
        !          1118:   fflush (stdout);
        !          1119:   sleep (1);
        !          1120: #endif
        !          1121:   if (! stop_input)
        !          1122:     queue_kbd_input ();
        !          1123:   if (c >= 0)
        !          1124:     kbd_buffer_store_char (c);
        !          1125: 
        !          1126:   errno = old_errno;
        !          1127: }
        !          1128: 
        !          1129: /* Wait until there is something in kbd_buffer.  */
        !          1130: 
        !          1131: wait_for_kbd_input ()
        !          1132: {
        !          1133:   extern int have_process_input, process_exited;
        !          1134: 
        !          1135:   /* If already something, avoid doing system calls.  */
        !          1136:   if (detect_input_pending ())
        !          1137:     {
        !          1138:       return;
        !          1139:     }
        !          1140:   /* Clear a flag, and tell ast routine above to set it.  */
        !          1141:   SYS$CLREF (input_ef);
        !          1142:   waiting_for_ast = 1;
        !          1143:   /* Check for timing error: ast happened while we were doing that.  */
        !          1144:   if (!detect_input_pending ())
        !          1145:     {
        !          1146:       /* No timing error: wait for flag to be set.  */
        !          1147:       SYS$WFLOR (input_ef, input_eflist);
        !          1148:       if (!detect_input_pending ())
        !          1149:        /* Check for subprocess input availability */
        !          1150:        {
        !          1151:          int dsp = have_process_input || process_exited;
        !          1152: 
        !          1153:          if (have_process_input)
        !          1154:            process_command_input ();
        !          1155:          if (process_exited)
        !          1156:            process_exit ();
        !          1157:          if (dsp)
        !          1158:            {
        !          1159:              RedoModes++;
        !          1160:              DoDsp (1);
        !          1161:            }
        !          1162:        }
        !          1163:     }
        !          1164:   waiting_for_ast = 0;
        !          1165: }
        !          1166: 
        !          1167: /* Get rid of any pending QIO, when we are about to suspend
        !          1168:    or when we want to throw away pending input.
        !          1169:    We wait for a positive sign that the AST routine has run
        !          1170:    and therefore there is no I/O request queued when we return.
        !          1171:    SYS$SETAST is used to avoid a timing error.  */
        !          1172: 
        !          1173: end_kbd_input()
        !          1174: {
        !          1175: #ifdef ASTDEBUG
        !          1176:   printf ("At end_kbd_input.\n");
        !          1177:   fflush (stdout);
        !          1178:   sleep (1);
        !          1179: #endif
        !          1180:   if (LIB$AST_IN_PROG ())  /* Don't wait if suspending from kbd_buffer_store_char! */
        !          1181:     {
        !          1182:       SYS$CANCEL (input_chan);
        !          1183:       return;
        !          1184:     }
        !          1185: 
        !          1186:   SYS$SETAST (0);
        !          1187:   /* Clear a flag, and tell ast routine above to set it.  */
        !          1188:   SYS$CLREF (input_ef);
        !          1189:   waiting_for_ast = 1;
        !          1190:   stop_input = 1;
        !          1191:   SYS$CANCEL (input_chan);
        !          1192:   SYS$SETAST (1);
        !          1193:   SYS$WAITFR (input_ef);
        !          1194:   waiting_for_ast = 0;
        !          1195: }
        !          1196: 
        !          1197: /* Wait for either input available or time interval expiry.  */
        !          1198: 
        !          1199: input_wait_timeout (timeval)
        !          1200:      int timeval;              /* Time to wait, in seconds */
        !          1201: {
        !          1202:   int time [2];
        !          1203:   
        !          1204:   LIB$EMUL (&timeval, &-10000000, &0, time);     /* Convert to VMS format */
        !          1205: 
        !          1206:   /* If already something, avoid doing system calls.  */
        !          1207:   if (detect_input_pending ())
        !          1208:     {
        !          1209:       return;
        !          1210:     }
        !          1211:   /* Clear a flag, and tell ast routine above to set it.  */
        !          1212:   SYS$CLREF (input_ef);
        !          1213:   waiting_for_ast = 1;
        !          1214:   /* Check for timing error: ast happened while we were doing that.  */
        !          1215:   if (!detect_input_pending ())
        !          1216:     {
        !          1217:       /* No timing error: wait for flag to be set.  */
        !          1218:       SYS$CANTIM (1, 0);
        !          1219:       if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
        !          1220:        SYS$WFLOR (timer_ef, timer_eflist);       /* Wait for timer expiry or input */
        !          1221:     }
        !          1222:   waiting_for_ast = 0;
        !          1223: }
        !          1224: 
        !          1225: /* The standard `sleep' routine works some other way
        !          1226:    and it stops working if you have ever quit out of it.
        !          1227:    This one continues to work.  */
        !          1228: 
        !          1229: sys_sleep (timeval)
        !          1230:      int timeval;
        !          1231: {
        !          1232:   int time [2];
        !          1233:   
        !          1234:   LIB$EMUL (&timeval, &-10000000, &0, time);     /* Convert to VMS format */
        !          1235: 
        !          1236:   SYS$CANTIM (1, 0);
        !          1237:   if (SYS$SETIMR (timer_ef, time, 0, 1) & 1) /* Set timer */
        !          1238:     SYS$WAITFR (timer_ef);       /* Wait for timer expiry only */
        !          1239: }
        !          1240: 
        !          1241: init_sigio ()
        !          1242: {
        !          1243:   request_sigio ();
        !          1244: }
        !          1245: 
        !          1246: reset_sigio ()
        !          1247: {
        !          1248:   unrequest_sigio ();
        !          1249: }
        !          1250: 
        !          1251: request_sigio ()
        !          1252: {
        !          1253:   croak ("request sigio");
        !          1254: }
        !          1255: 
        !          1256: unrequest_sigio ()
        !          1257: {
        !          1258:   croak ("unrequest sigio");
        !          1259: }
        !          1260: 
        !          1261: #endif /* VMS */
        !          1262: 
        !          1263: /* Note that VMS compiler won't accept defined (CANNOT_DUMP).  */
        !          1264: #ifndef CANNOT_DUMP
        !          1265: #define NEED_STARTS
        !          1266: #endif
        !          1267: 
        !          1268: #ifndef SYSTEM_MALLOC
        !          1269: #ifndef NEED_STARTS
        !          1270: #define NEED_STARTS
        !          1271: #endif
        !          1272: #endif
        !          1273: 
        !          1274: #ifdef NEED_STARTS
        !          1275: /* Some systems that cannot dump also cannot implement these.  */
        !          1276: 
        !          1277: /*
        !          1278:  *     Return the address of the start of the text segment prior to
        !          1279:  *     doing an unexec().  After unexec() the return value is undefined.
        !          1280:  *     See crt0.c for further explanation and _start().
        !          1281:  *
        !          1282:  */
        !          1283: 
        !          1284: #ifndef CANNOT_UNEXEC
        !          1285: char *
        !          1286: start_of_text ()
        !          1287: {
        !          1288: #ifdef TEXT_START
        !          1289:   return ((char *) TEXT_START);
        !          1290: #else
        !          1291: #ifdef GOULD
        !          1292:   extern csrt();
        !          1293:   return ((char *) csrt);
        !          1294: #else /* not GOULD */
        !          1295:   extern int _start ();
        !          1296:   return ((char *) _start);
        !          1297: #endif /* GOULD */
        !          1298: #endif /* TEXT_START */
        !          1299: }
        !          1300: #endif /* not CANNOT_UNEXEC */
        !          1301: 
        !          1302: /*
        !          1303:  *     Return the address of the start of the data segment prior to
        !          1304:  *     doing an unexec().  After unexec() the return value is undefined.
        !          1305:  *     See crt0.c for further information and definition of data_start.
        !          1306:  *
        !          1307:  *     Apparently, on BSD systems this is etext at startup.  On
        !          1308:  *     USG systems (swapping) this is highly mmu dependent and
        !          1309:  *     is also dependent on whether or not the program is running
        !          1310:  *     with shared text.  Generally there is a (possibly large)
        !          1311:  *     gap between end of text and start of data with shared text.
        !          1312:  *
        !          1313:  *     On Uniplus+ systems with shared text, data starts at a
        !          1314:  *     fixed address.  Each port (from a given oem) is generally
        !          1315:  *     different, and the specific value of the start of data can
        !          1316:  *     be obtained via the UniPlus+ specific "uvar(2)" system call,
        !          1317:  *     however the method outlined in crt0.c seems to be more portable.
        !          1318:  *
        !          1319:  *     Probably what will have to happen when a USG unexec is available,
        !          1320:  *     at least on UniPlus, is temacs will have to be made unshared so
        !          1321:  *     that text and data are contiguous.  Then once loadup is complete,
        !          1322:  *     unexec will produce a shared executable where the data can be
        !          1323:  *     at the normal shared text boundry and the startofdata variable
        !          1324:  *     will be patched by unexec to the correct value.
        !          1325:  *
        !          1326:  */
        !          1327:  
        !          1328: char *
        !          1329: start_of_data ()
        !          1330: {
        !          1331: #ifdef DATA_START
        !          1332:   return ((char *) DATA_START);
        !          1333: #else
        !          1334:   extern int data_start;
        !          1335:   return ((char *) &data_start);
        !          1336: #endif
        !          1337: }
        !          1338: #endif /* NEED_STARTS (not CANNOT_DUMP or not SYSTEM_MALLOC) */
        !          1339: 
        !          1340: #ifndef CANNOT_DUMP
        !          1341: /* Some systems that cannot dump also cannot implement these.  */
        !          1342: 
        !          1343: /*
        !          1344:  *     Return the address of the end of the text segment prior to
        !          1345:  *     doing an unexec().  After unexec() the return value is undefined.
        !          1346:  */
        !          1347:  
        !          1348: char *
        !          1349: end_of_text ()
        !          1350: {
        !          1351: #ifdef TEXT_END
        !          1352:   return ((char *) TEXT_END);
        !          1353: #else
        !          1354:   extern int etext;
        !          1355:   return ((char *) &etext);
        !          1356: #endif
        !          1357: }
        !          1358:  
        !          1359: /*
        !          1360:  *     Return the address of the end of the data segment prior to
        !          1361:  *     doing an unexec().  After unexec() the return value is undefined.
        !          1362:  */
        !          1363: 
        !          1364: char *
        !          1365: end_of_data ()
        !          1366: {
        !          1367: #ifdef DATA_END
        !          1368:   return ((char *) DATA_END);
        !          1369: #else
        !          1370:   extern int edata;
        !          1371:   return ((char *) &edata);
        !          1372: #endif
        !          1373: }
        !          1374: 
        !          1375: #endif /* not CANNOT_DUMP */
        !          1376: 
        !          1377: /* Get_system_name returns as its value
        !          1378:  a string for the Lisp function system-name to return. */
        !          1379: 
        !          1380: #ifdef BSD4_1
        !          1381: #include <whoami.h>
        !          1382: #endif
        !          1383: 
        !          1384: #ifdef USG
        !          1385: /* Can't have this within the function since `static' is #defined to nothing */
        !          1386: static struct utsname get_system_name_name;
        !          1387: #endif
        !          1388: 
        !          1389: char *
        !          1390: get_system_name ()
        !          1391: {
        !          1392: #ifdef USG
        !          1393:   uname (&get_system_name_name);
        !          1394:   return (get_system_name_name.nodename);
        !          1395: #else /* Not USG */
        !          1396: #ifdef BSD4_1
        !          1397:   return sysname;
        !          1398: #else /* not USG, not 4.1 */
        !          1399:   static char system_name_saved[32];
        !          1400: #ifdef VMS
        !          1401:   char *sp;
        !          1402:   if ((sp = egetenv("SYS$NODE")) == 0)
        !          1403:     sp = "vax-vms";
        !          1404:   else
        !          1405:     {
        !          1406:       char *end;
        !          1407: 
        !          1408:       if ((end = index (sp, ':')) != 0)
        !          1409:        *end = '\0';
        !          1410:     }
        !          1411:   strcpy (system_name_saved, sp);
        !          1412: #else /* not VMS */
        !          1413:   gethostname (system_name_saved, sizeof (system_name_saved));
        !          1414: #endif /* not VMS */
        !          1415:   return system_name_saved;
        !          1416: #endif /* not USG, not 4.1 */
        !          1417: #endif /* not USG */
        !          1418: }
        !          1419: 
        !          1420: #ifndef HAVE_SELECT
        !          1421: 
        !          1422: /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
        !          1423:  * Only checks read descriptors.
        !          1424:  */
        !          1425: /* How long to wait between checking fds in select */
        !          1426: #define SELECT_PAUSE 1
        !          1427: int select_alarmed;
        !          1428: 
        !          1429: /* For longjmp'ing back to read_input_waiting.  */
        !          1430: 
        !          1431: jmp_buf read_alarm_throw;
        !          1432: 
        !          1433: /* Nonzero if the alarm signal should throw back to read_input_waiting.
        !          1434:    The read_socket_hook function sets this to 1 while it is waiting.  */
        !          1435: 
        !          1436: int read_alarm_should_throw;
        !          1437: 
        !          1438: select_alarm ()
        !          1439: {
        !          1440:   select_alarmed = 1;
        !          1441: #ifdef BSD4_1
        !          1442:   sigrelse (SIGALRM);
        !          1443: #else /* not BSD4_1 */
        !          1444:   signal (SIGALRM, SIG_IGN);
        !          1445: #endif /* not BSD4_1 */
        !          1446:   if (read_alarm_should_throw)
        !          1447:     longjmp (read_alarm_throw, 1);
        !          1448: }
        !          1449: 
        !          1450: /* Only rfds are checked and timeout must point somewhere */
        !          1451: int
        !          1452: select (nfds, rfds, wfds, efds, timeout)
        !          1453:      int nfds;
        !          1454:      int *rfds, *wfds, *efds, *timeout;
        !          1455: {
        !          1456:   int ravail = 0, orfds = 0, old_alarm;
        !          1457:   extern int kbd_count;
        !          1458:   extern int proc_buffered_char[];
        !          1459: #ifndef subprocesses
        !          1460:   int child_changed = 0;
        !          1461: #else
        !          1462:   extern int child_changed;
        !          1463: #endif
        !          1464:   int (*old_trap) ();
        !          1465:   char buf;
        !          1466: 
        !          1467:   if (rfds)
        !          1468:     {
        !          1469:       orfds = *rfds;
        !          1470:       *rfds = 0;
        !          1471:     }
        !          1472:   if (wfds)
        !          1473:     *wfds = 0;
        !          1474:   if (efds)
        !          1475:     *efds = 0;
        !          1476: 
        !          1477:   /* If we are looking only for the terminal, with no timeout,
        !          1478:      just read it and wait -- that's more efficient.  */
        !          1479:   if (orfds == 1 && *timeout == 100000 && !child_changed)
        !          1480:     {
        !          1481:       if (!kbd_count)
        !          1482:        read_input_waiting ();
        !          1483:       *rfds = 1;
        !          1484:       return 1;
        !          1485:     }
        !          1486: 
        !          1487:   /* Once a second, till the timer expires, check all the flagged read
        !          1488:    * descriptors to see if any input is available.  If there is some then
        !          1489:    * set the corresponding bit in the return copy of rfds.
        !          1490:    */ 
        !          1491:   while (1)
        !          1492:     {
        !          1493:       register int to_check, bit, fd;
        !          1494: 
        !          1495:       if (rfds)
        !          1496:        {
        !          1497:          for (to_check = nfds, bit = 1, fd = 0; --to_check >= 0; bit <<= 1, fd++)
        !          1498:            {
        !          1499:              if (orfds & bit)
        !          1500:                {
        !          1501:                  int avail = 0, status = 0;
        !          1502: 
        !          1503:                  if (bit == 1)
        !          1504:                    avail = detect_input_pending(); /* Special keyboard handler */
        !          1505:                  else
        !          1506:                    {
        !          1507: #ifdef FIONREAD
        !          1508:                      status = ioctl (fd, FIONREAD, &avail);
        !          1509: #else /* no FIONREAD */
        !          1510:                      /* Hoping it will return -1 if nothing available
        !          1511:                         or 0 if all 0 chars requested are read.  */
        !          1512:                      if (proc_buffered_char[fd] >= 0)
        !          1513:                        avail = 1;
        !          1514:                      else
        !          1515:                        {
        !          1516:                          avail = read (fd, &buf, 1);
        !          1517:                          if (avail > 0)
        !          1518:                            proc_buffered_char[fd] = buf;
        !          1519:                        }
        !          1520: #endif /* no FIONREAD */
        !          1521:                    }
        !          1522:                  if (status >= 0 && avail > 0)
        !          1523:                    {
        !          1524:                      (*rfds) |= bit;
        !          1525:                      ravail++;
        !          1526:                    }
        !          1527:                }
        !          1528:            }
        !          1529:        }
        !          1530:       if (*timeout == 0 || ravail != 0 || child_changed)
        !          1531:        break;
        !          1532:       old_alarm = alarm (0);
        !          1533:       old_trap = (int (*)()) signal (SIGALRM, select_alarm);
        !          1534:       select_alarmed = 0;
        !          1535:       alarm (SELECT_PAUSE);
        !          1536:       /* Wait for a SIGALRM (or maybe a SIGTINT) */
        !          1537:       while (select_alarmed == 0 && *timeout != 0 && child_changed == 0)
        !          1538:        {
        !          1539:          /* If we are interested in terminal input,
        !          1540:             wait by reading the terminal.
        !          1541:             That makes instant wakeup for terminal input at least.  */
        !          1542:          if (orfds & 1)
        !          1543:            {
        !          1544:              read_input_waiting ();
        !          1545:              if (kbd_count)
        !          1546:                select_alarmed = 1;
        !          1547:            }
        !          1548:          else
        !          1549:            pause();
        !          1550:        }
        !          1551:       (*timeout) -= SELECT_PAUSE;
        !          1552:       /* Reset the old alarm if there was one */
        !          1553:       alarm (0);
        !          1554:       signal (SIGALRM, old_trap);
        !          1555:       if (old_alarm != 0)
        !          1556:        {
        !          1557:          /* Reset or forge an interrupt for the original handler. */
        !          1558:          old_alarm -= SELECT_PAUSE;
        !          1559:          if (old_alarm <= 0)
        !          1560:            kill (getpid (), SIGALRM); /* Fake an alarm with the orig' handler */
        !          1561:          else
        !          1562:            alarm (old_alarm);
        !          1563:        }
        !          1564:       if (*timeout == 0)  /* Stop on timer being cleared */
        !          1565:        break;
        !          1566:     }
        !          1567:   return ravail;
        !          1568: }
        !          1569: 
        !          1570: /* Read keyboard input into the standard buffer,
        !          1571:    waiting for at least one character.  */
        !          1572: 
        !          1573: /* Make all keyboard buffers much bigger when using X windows.  */
        !          1574: #ifdef HAVE_X_WINDOWS
        !          1575: #define BUFFER_SIZE_FACTOR 16
        !          1576: #else
        !          1577: #define BUFFER_SIZE_FACTOR 1
        !          1578: #endif
        !          1579: 
        !          1580: read_input_waiting ()
        !          1581: {
        !          1582:   extern int kbd_count;
        !          1583:   extern unsigned char kbd_buffer[];
        !          1584:   extern unsigned char *kbd_ptr;
        !          1585:   int val;
        !          1586: 
        !          1587:   if (read_socket_hook)
        !          1588:     {
        !          1589:       read_alarm_should_throw = 0;
        !          1590:       if (! setjmp (read_alarm_throw))
        !          1591:        val = (*read_socket_hook) (0, kbd_buffer, 256 * BUFFER_SIZE_FACTOR);
        !          1592:       else
        !          1593:        val = -1;
        !          1594:     }
        !          1595:   else
        !          1596:     val = read (fileno (stdin), kbd_buffer, 1);
        !          1597: 
        !          1598:   if (val > 0)
        !          1599:     {
        !          1600:       kbd_ptr = kbd_buffer;
        !          1601:       kbd_count = val;
        !          1602:     }
        !          1603: }
        !          1604: 
        !          1605: #endif /* not HAVE_SELECT */
        !          1606: 
        !          1607: #ifdef BSD4_1
        !          1608: /* VARARGS */
        !          1609: setpriority ()
        !          1610: {
        !          1611:   return 0;
        !          1612: }
        !          1613: 
        !          1614: /*
        !          1615:  * Partially emulate 4.2 open call.
        !          1616:  * open is defined as this in 4.1.
        !          1617:  *
        !          1618:  * - added by Michael Bloom @ Citicorp/TTI
        !          1619:  *
        !          1620:  */
        !          1621: 
        !          1622: int
        !          1623: sys_open (path, oflag, mode)
        !          1624:      char *path;
        !          1625:      int oflag, mode;
        !          1626: {
        !          1627:   if (oflag & O_CREAT) 
        !          1628:     return creat (path, mode);
        !          1629:   else
        !          1630:     return open (path, oflag);
        !          1631: }
        !          1632: 
        !          1633: init_sigio ()
        !          1634: {
        !          1635:   if (noninteractive)
        !          1636:     return;
        !          1637:   lmode = LINTRUP | lmode;
        !          1638:   ioctl (0, TIOCLSET, &lmode);
        !          1639: }
        !          1640: 
        !          1641: reset_sigio ()
        !          1642: {
        !          1643:   if (noninteractive)
        !          1644:     return;
        !          1645:   lmode = ~LINTRUP & lmode;
        !          1646:   ioctl (0, TIOCLSET, &lmode);
        !          1647: }
        !          1648: 
        !          1649: request_sigio ()
        !          1650: {
        !          1651:   sigrelse (SIGTINT);
        !          1652: 
        !          1653:   interrupts_deferred = 0;
        !          1654: }
        !          1655: 
        !          1656: unrequest_sigio ()
        !          1657: {
        !          1658:   sighold (SIGTINT);
        !          1659: 
        !          1660:   interrupts_deferred = 1;
        !          1661: }
        !          1662: 
        !          1663: /* still inside #ifdef BSD4_1 */
        !          1664: #ifdef subprocesses
        !          1665: 
        !          1666: int sigheld; /* Mask of held signals */
        !          1667: 
        !          1668: sigholdx (signum)
        !          1669:      int signum;
        !          1670: {
        !          1671:   sigheld |= sigbit (signum);
        !          1672:   sighold (signum);
        !          1673: }
        !          1674: 
        !          1675: sigisheld (signum)
        !          1676:      int signum;
        !          1677: {
        !          1678:   sigheld |= sigbit (signum);
        !          1679: }
        !          1680: 
        !          1681: sigunhold (signum)
        !          1682:      int signum;
        !          1683: {
        !          1684:   sigheld &= ~sigbit (signum);
        !          1685:   sigrelse (signum);
        !          1686: }
        !          1687: 
        !          1688: sigfree ()    /* Free all held signals */
        !          1689: {
        !          1690:   int i;
        !          1691:   for (i = 0; i < NSIG; i++)
        !          1692:     if (sigheld & sigbit (i))
        !          1693:       sigrelse (i);
        !          1694:   sigheld = 0;
        !          1695: }
        !          1696: 
        !          1697: sigbit (i)
        !          1698: {
        !          1699:   return 1 << (i - 1);
        !          1700: }
        !          1701: #endif /* subprocesses */
        !          1702: #endif /* BSD4_1 */
        !          1703: 
        !          1704: #ifndef BSTRING
        !          1705: 
        !          1706: void
        !          1707: bzero (b, length)
        !          1708:      register char *b;
        !          1709:      register int length;
        !          1710: {
        !          1711: #ifdef VMS
        !          1712:   short zero = 0;
        !          1713:   long max_str = 65535;
        !          1714: 
        !          1715:   while (length > max_str) {
        !          1716:     (void) LIB$MOVC5 (&zero, &zero, &zero, &max_str, b);
        !          1717:     length -= max_str;
        !          1718:     b += max_str;
        !          1719:   }
        !          1720:   (void) LIB$MOVC5 (&zero, &zero, &zero, &length, b);
        !          1721: #else
        !          1722:   while (length-- > 0)
        !          1723:     *b++ = 0;
        !          1724: #endif /* not VMS */
        !          1725: }
        !          1726: 
        !          1727: /* Saying `void' requires a declaration, above, where bcopy is used
        !          1728:    and that declaration causes pain for systems where bcopy is a macro.  */
        !          1729: bcopy (b1, b2, length)
        !          1730:      register char *b1;
        !          1731:      register char *b2;
        !          1732:      register int length;
        !          1733: {
        !          1734: #ifdef VMS
        !          1735:   long max_str = 65535;
        !          1736: 
        !          1737:   while (length > max_str) {
        !          1738:     (void) LIB$MOVC3 (&max_str, b1, b2);
        !          1739:     length -= max_str;
        !          1740:     b1 += max_str;
        !          1741:     b2 += max_str;
        !          1742:   }
        !          1743:   (void) LIB$MOVC3 (&length, b1, b2);
        !          1744: #else
        !          1745:   while (length-- > 0)
        !          1746:     *b2++ = *b1++;
        !          1747: #endif /* not VMS */
        !          1748: }
        !          1749: 
        !          1750: int
        !          1751: bcmp (b1, b2, length)  /* This could be a macro! */
        !          1752:      register char *b1;
        !          1753:      register char *b2;
        !          1754:      register int length;
        !          1755: {
        !          1756: #ifdef VMS
        !          1757:   struct dsc$descriptor_s src1 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b1};
        !          1758:   struct dsc$descriptor_s src2 = {length, DSC$K_DTYPE_T, DSC$K_CLASS_S, b2};
        !          1759: 
        !          1760:   return STR$COMPARE (&src1, &src2);
        !          1761: #else
        !          1762:   while (length-- > 0)
        !          1763:     if (*b1++ != *b2++)
        !          1764:       return 1;
        !          1765: 
        !          1766:   return 0;
        !          1767: #endif /* not VMS */
        !          1768: }
        !          1769: #endif /* not BSTRING */
        !          1770: 
        !          1771: #ifdef BSD4_1
        !          1772: long random ()
        !          1773: {
        !          1774:   return (rand ());
        !          1775: }
        !          1776: 
        !          1777: srandom (arg)
        !          1778:      int arg;
        !          1779: {
        !          1780:   srand (arg);
        !          1781: }
        !          1782: #endif BSD4_1
        !          1783: 
        !          1784: #ifdef USG
        !          1785: /*
        !          1786:  *     The BSD random(3) returns numbers in the range of
        !          1787:  *     0 to 2e31 - 1.  The USG rand(3C) returns numbers in the
        !          1788:  *     range of 0 to 2e15 - 1.  This is probably not significant
        !          1789:  *     in this usage.
        !          1790:  */
        !          1791:   
        !          1792: long
        !          1793: random ()
        !          1794: {
        !          1795:   /* Arrange to return a range centered on zero.  */
        !          1796:   return rand () - (1 << 14);
        !          1797: }
        !          1798: 
        !          1799: srandom (arg)
        !          1800:      int arg;
        !          1801: {
        !          1802:   srand (arg);
        !          1803: }
        !          1804: 
        !          1805: #endif /* USG */
        !          1806: 
        !          1807: 
        !          1808: #ifdef VMS
        !          1809: 
        !          1810: #ifdef getenv
        !          1811: /* If any place else asks for the TERM variable,
        !          1812:    allow it to be overridden with the EMACS_TERM variable
        !          1813:    before attempting to translate the logical name TERM.  As a last
        !          1814:    resort, ask for VAX C's special idea of the TERM variable.  */
        !          1815: #undef getenv
        !          1816: char *
        !          1817: sys_getenv (name)
        !          1818:      char *name;
        !          1819: {
        !          1820:   register char *val;
        !          1821:   static char buf[256];
        !          1822:   static struct dsc$descriptor_s equiv
        !          1823:     = {sizeof(buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf};
        !          1824:   static struct dsc$descriptor_s d_name
        !          1825:     = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0};
        !          1826:   short eqlen;
        !          1827: 
        !          1828:   if (!strcmp (name, "TERM"))
        !          1829:     {
        !          1830:       val = (char *) getenv ("EMACS_TERM");
        !          1831:       if (val)
        !          1832:        return val;
        !          1833:     }
        !          1834: 
        !          1835:   d_name.dsc$w_length = strlen (name);
        !          1836:   d_name.dsc$a_pointer = name;
        !          1837:   if (lib$sys_trnlog (&d_name, &eqlen, &equiv) == 1)
        !          1838:     {
        !          1839:       char *str = (char *) xmalloc (eqlen + 1);
        !          1840:       bcopy (buf, str, eqlen);
        !          1841:       str[eqlen] = '\0';
        !          1842:       /* This is a storage leak, but a pain to fix.  With luck,
        !          1843:         no one will ever notice.  */
        !          1844:       return str;
        !          1845:     }
        !          1846:   return (char *) getenv (name);
        !          1847: }
        !          1848: #endif /* getenv */
        !          1849: 
        !          1850: #ifdef abort
        !          1851: /* Since VMS doesn't believe in core dumps, the only way to debug this beast is
        !          1852:    to force a call on the debugger from within the image. */
        !          1853: #undef abort
        !          1854: sys_abort ()
        !          1855: {
        !          1856:   reset_sys_modes ();
        !          1857:   LIB$SIGNAL (SS$_DEBUG);
        !          1858: }
        !          1859: #endif /* abort */
        !          1860: #endif /* VMS */
        !          1861: 
        !          1862: #ifdef VMS
        !          1863: #ifdef LINK_CRTL_SHARE
        !          1864: #ifdef SHAREABLE_LIB_BUG
        !          1865: /* Variables declared noshare and initialized in shareable libraries
        !          1866:    cannot be shared.  The VMS linker incorrectly forces you to use a private
        !          1867:    version which is uninitialized... If not for this "feature", we
        !          1868:    could use the C library definition of sys_nerr and sys_errlist. */
        !          1869: int sys_nerr = 35;
        !          1870: char *sys_errlist[] =
        !          1871:   {
        !          1872:     "error 0",
        !          1873:     "not owner",
        !          1874:     "no such file or directory",
        !          1875:     "no such process",
        !          1876:     "interrupted system call",
        !          1877:     "i/o error",
        !          1878:     "no such device or address",
        !          1879:     "argument list too long",
        !          1880:     "exec format error",
        !          1881:     "bad file number",
        !          1882:     "no child process",
        !          1883:     "no more processes",
        !          1884:     "not enough memory",
        !          1885:     "permission denied",
        !          1886:     "bad address",
        !          1887:     "block device required",
        !          1888:     "mount devices busy",
        !          1889:     "file exists",
        !          1890:     "cross-device link",
        !          1891:     "no such device",
        !          1892:     "not a directory",
        !          1893:     "is a directory",
        !          1894:     "invalid argument",
        !          1895:     "file table overflow",
        !          1896:     "too many open files",
        !          1897:     "not a typewriter",
        !          1898:     "text file busy",
        !          1899:     "file too big",
        !          1900:     "no space left on device",
        !          1901:     "illegal seek",
        !          1902:     "read-only file system",
        !          1903:     "too many links",
        !          1904:     "broken pipe",
        !          1905:     "math argument",
        !          1906:     "result too large",
        !          1907:     "I/O stream empty",
        !          1908:     "vax/vms specific error code nontranslatable error"
        !          1909:   };
        !          1910: #endif /* SHAREABLE_LIB_BUG */
        !          1911: #endif /* LINK_CRTL_SHARE */
        !          1912: #endif /* VMS */
        !          1913: 
        !          1914: #ifdef INTERRUPTABLE_OPEN
        !          1915: 
        !          1916: int
        !          1917: /* VARARGS 2 */
        !          1918: sys_open (path, oflag, mode)
        !          1919:      char *path;
        !          1920:      int oflag, mode;
        !          1921: {
        !          1922:   register int rtnval;
        !          1923:   
        !          1924:   while ((rtnval = open (path, oflag, mode)) == -1 && errno == EINTR);
        !          1925:   return (rtnval);
        !          1926: }
        !          1927: 
        !          1928: #endif /* INTERRUPTABLE_OPEN */
        !          1929: 
        !          1930: #ifdef INTERRUPTABLE_CLOSE
        !          1931: 
        !          1932: sys_close (fd)
        !          1933:      int fd;
        !          1934: {
        !          1935:   register int rtnval;
        !          1936: 
        !          1937:   while ((rtnval = close(fd)) == -1 && errno == EINTR);
        !          1938:   return rtnval;
        !          1939: }
        !          1940: 
        !          1941: #endif /* INTERRUPTABLE_CLOSE */
        !          1942: 
        !          1943: #ifdef INTERRUPTABLE_IO
        !          1944: 
        !          1945: int
        !          1946: sys_read (fildes, buf, nbyte)
        !          1947:      int fildes;
        !          1948:      char *buf;
        !          1949:      unsigned int nbyte;
        !          1950: {
        !          1951:   register int rtnval;
        !          1952:   
        !          1953:   while ((rtnval = read (fildes, buf, nbyte)) == -1 && errno == EINTR);
        !          1954:   return (rtnval);
        !          1955: }
        !          1956: 
        !          1957: int
        !          1958: sys_write (fildes, buf, nbyte)
        !          1959:      int fildes;
        !          1960:      char *buf;
        !          1961:      unsigned int nbyte;
        !          1962: {
        !          1963:   register int rtnval;
        !          1964: 
        !          1965:   while ((rtnval = write (fildes, buf, nbyte)) == -1 && errno == EINTR);
        !          1966:   return (rtnval);
        !          1967: }
        !          1968: 
        !          1969: #endif /* INTERRUPTABLE_IO */
        !          1970: 
        !          1971: #ifdef USG
        !          1972: /*
        !          1973:  *     All of the following are for USG.
        !          1974:  *
        !          1975:  *     On USG systems the system calls are interruptable by signals
        !          1976:  *     that the user program has elected to catch.  Thus the system call
        !          1977:  *     must be retried in these cases.  To handle this without massive
        !          1978:  *     changes in the source code, we remap the standard system call names
        !          1979:  *     to names for our own functions in sysdep.c that do the system call
        !          1980:  *     with retries.  Actually, for portability reasons, it is good
        !          1981:  *     programming practice, as this example shows, to limit all actual
        !          1982:  *     system calls to a single occurance in the source.  Sure, this
        !          1983:  *     adds an extra level of function call overhead but it is almost
        !          1984:  *     always negligible.   Fred Fish, Unisoft Systems Inc.
        !          1985:  */
        !          1986: 
        !          1987: char *sys_siglist[NSIG + 1] =
        !          1988: {
        !          1989: #ifdef IBMRTAIX
        !          1990: /* AIX has changed the signals a bit */
        !          1991:   "bogus signal",                      /* 0 */
        !          1992:   "hangup",                            /* 1  SIGHUP */
        !          1993:   "interrupt",                         /* 2  SIGINT */
        !          1994:   "quit",                              /* 3  SIGQUIT */
        !          1995:   "illegal instruction",               /* 4  SIGILL */
        !          1996:   "trace trap",                                /* 5  SIGTRAP */
        !          1997:   "IOT instruction",                   /* 6  SIGIOT */
        !          1998:   "crash likely",                      /* 7  SIGDANGER */
        !          1999:   "floating point exception",          /* 8  SIGFPE */
        !          2000:   "kill",                              /* 9  SIGKILL */
        !          2001:   "bus error",                         /* 10 SIGBUS */
        !          2002:   "segmentation violation",            /* 11 SIGSEGV */
        !          2003:   "bad argument to system call",       /* 12 SIGSYS */
        !          2004:   "write on a pipe with no one to read it", /* 13 SIGPIPE */
        !          2005:   "alarm clock",                       /* 14 SIGALRM */
        !          2006:   "software termination signum",       /* 15 SIGTERM */
        !          2007:   "user defined signal 1",             /* 16 SIGUSR1 */
        !          2008:   "user defined signal 2",             /* 17 SIGUSR2 */
        !          2009:   "death of a child",                  /* 18 SIGCLD */
        !          2010:   "power-fail restart",                        /* 19 SIGPWR */
        !          2011:   "bogus signal",                      /* 20 */
        !          2012:   "bogus signal",                      /* 21 */
        !          2013:   "bogus signal",                      /* 22 */
        !          2014:   "bogus signal",                      /* 23 */
        !          2015:   "bogus signal",                      /* 24 */
        !          2016:   "LAN I/O interrupt",                 /* 25 SIGAIO */
        !          2017:   "PTY I/O interrupt",                 /* 26 SIGPTY */
        !          2018:   "I/O intervention required",         /* 27 SIGIOINT */
        !          2019:   "HFT grant",                         /* 28 SIGGRANT */
        !          2020:   "HFT retract",                       /* 29 SIGRETRACT */
        !          2021:   "HFT sound done",                    /* 30 SIGSOUND */
        !          2022:   "HFT input ready",                   /* 31 SIGMSG */
        !          2023: #else /* not IBMRTAIX */
        !          2024:   "bogus signal",                      /* 0 */
        !          2025:   "hangup",                            /* 1  SIGHUP */
        !          2026:   "interrupt",                         /* 2  SIGINT */
        !          2027:   "quit",                              /* 3  SIGQUIT */
        !          2028:   "illegal instruction",               /* 4  SIGILL */
        !          2029:   "trace trap",                                /* 5  SIGTRAP */
        !          2030:   "IOT instruction",                   /* 6  SIGIOT */
        !          2031:   "EMT instruction",                   /* 7  SIGEMT */
        !          2032:   "floating point exception",          /* 8  SIGFPE */
        !          2033:   "kill",                              /* 9  SIGKILL */
        !          2034:   "bus error",                         /* 10 SIGBUS */
        !          2035:   "segmentation violation",            /* 11 SIGSEGV */
        !          2036:   "bad argument to system call",       /* 12 SIGSYS */
        !          2037:   "write on a pipe with no one to read it", /* 13 SIGPIPE */
        !          2038:   "alarm clock",                       /* 14 SIGALRM */
        !          2039:   "software termination signum",       /* 15 SIGTERM */
        !          2040:   "user defined signal 1",             /* 16 SIGUSR1 */
        !          2041:   "user defined signal 2",             /* 17 SIGUSR2 */
        !          2042:   "death of a child",                  /* 18 SIGCLD */
        !          2043:   "power-fail restart",                        /* 19 SIGPWR */
        !          2044: #endif /* not IBMRTAIX */
        !          2045:   0
        !          2046:   };
        !          2047: 
        !          2048: /*
        !          2049:  *     Warning, this function may not duplicate 4.2 action properly
        !          2050:  *     under error conditions.
        !          2051:  */
        !          2052: 
        !          2053: #ifndef MAXPATHLEN
        !          2054: /* In 4.1, param.h fails to define this.  */
        !          2055: #define MAXPATHLEN 1024
        !          2056: #endif
        !          2057: 
        !          2058: #ifndef HAVE_GETWD
        !          2059: 
        !          2060: char *
        !          2061: getwd (pathname)
        !          2062:      char *pathname;
        !          2063: {
        !          2064:   char *npath, *spath;
        !          2065:   extern char *getcwd ();
        !          2066: 
        !          2067:   spath = npath = getcwd ((char *) 0, MAXPATHLEN);
        !          2068:   /* On Altos 3068, getcwd can return @hostname/dir, so discard
        !          2069:      up to first slash.  Should be harmless on other systems.  */
        !          2070:   while (*npath && *npath != '/')
        !          2071:     npath++;
        !          2072:   strcpy (pathname, npath);
        !          2073:   free (spath);                        /* getcwd uses malloc */
        !          2074:   return pathname;
        !          2075: }
        !          2076: 
        !          2077: #endif HAVE_GETWD
        !          2078: 
        !          2079: /*
        !          2080:  *     Emulate rename using unlink/link.  Note that this is
        !          2081:  *     only partially correct.  Also, doesn't enforce restriction
        !          2082:  *     that files be of same type (regular->regular, dir->dir, etc).
        !          2083:  */
        !          2084: 
        !          2085: rename (from, to)
        !          2086:      char *from;
        !          2087:      char *to;
        !          2088: {
        !          2089:   if (access (from, 0) == 0)
        !          2090:     {
        !          2091:       unlink (to);
        !          2092:       if (link (from, to) == 0)
        !          2093:        if (unlink (from) == 0)
        !          2094:          return (0);
        !          2095:     }
        !          2096:   return (-1);
        !          2097: }
        !          2098: 
        !          2099: /* VARARGS */
        !          2100: setpriority ()
        !          2101: {
        !          2102:   return (0);
        !          2103: }
        !          2104: 
        !          2105: #ifndef HAVE_VFORK
        !          2106: 
        !          2107: /*
        !          2108:  *     Substitute fork(2) for vfork(2) on USG flavors.
        !          2109:  */
        !          2110: 
        !          2111: vfork ()
        !          2112: {
        !          2113:   return (fork ());
        !          2114: }
        !          2115: 
        !          2116: #endif /* not HAVE_VFORK */
        !          2117: 
        !          2118: #ifdef MISSING_UTIMES
        !          2119: 
        !          2120: /* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes.  */
        !          2121: 
        !          2122: utimes ()
        !          2123: {
        !          2124: }
        !          2125: #endif
        !          2126: 
        !          2127: #ifdef IRIS_UTIME
        !          2128: 
        !          2129: /* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the
        !          2130:    utimbuf structure defined anywhere but in the man page. */
        !          2131: 
        !          2132: struct utimbuf
        !          2133:  {
        !          2134:    long actime;
        !          2135:    long modtime;
        !          2136:  };
        !          2137: 
        !          2138: utimes (name, tvp)
        !          2139:      char *name;
        !          2140:      struct timeval tvp[];
        !          2141: {
        !          2142:   struct utimbuf utb;
        !          2143:   utb.actime  = tvp[0].tv_sec;
        !          2144:   utb.modtime = tvp[1].tv_sec;
        !          2145:   utime (name, &utb);
        !          2146: }
        !          2147: #endif /* IRIS_UTIME */
        !          2148: 
        !          2149: 
        !          2150: #ifdef HPUX
        !          2151: 
        !          2152: /* HPUX curses library references perror, but as far as we know
        !          2153:    it won't be called.  Anyway this definition will do for now.  */
        !          2154: 
        !          2155: perror ()
        !          2156: {
        !          2157: }
        !          2158: 
        !          2159: #endif /* HPUX */
        !          2160: 
        !          2161: #ifndef HAVE_DUP2
        !          2162: 
        !          2163: /*
        !          2164:  *     Emulate BSD dup2(2).  First close newd if it already exists.
        !          2165:  *     Then, attempt to dup oldd.  If not successful, call dup2 recursively
        !          2166:  *     until we are, then close the unsuccessful ones.
        !          2167:  */
        !          2168: 
        !          2169: dup2 (oldd, newd)
        !          2170:      int oldd;
        !          2171:      int newd;
        !          2172: {
        !          2173:   register int fd;
        !          2174:   
        !          2175:   sys_close (newd);
        !          2176: 
        !          2177: #ifdef F_DUPFD
        !          2178:   fd = fcntl (oldd, F_DUPFD, newd);
        !          2179:   if (fd != newd)
        !          2180:     error ("cant dup2(%i,%i) : %s", oldd, newd, sys_errlist[errno]);
        !          2181: #else
        !          2182:   while ((fd = dup (oldd)) != newd)
        !          2183:     {
        !          2184:       dup2 (oldd, newd);
        !          2185:       sys_close (fd);
        !          2186:     }
        !          2187: #endif
        !          2188: }
        !          2189: 
        !          2190: #endif /* not HAVE_DUP2 */
        !          2191: 
        !          2192: /*
        !          2193:  *     Gettimeofday.  Simulate as much as possible.  Only accurate
        !          2194:  *     to nearest second.  Emacs doesn't use tzp so ignore it for now.
        !          2195:  *     Only needed when subprocesses are defined.
        !          2196:  */
        !          2197: 
        !          2198: #ifdef subprocesses
        !          2199: #ifndef HAVE_GETTIMEOFDAY
        !          2200: #ifdef HAVE_TIMEVAL
        !          2201:  
        !          2202: /* ARGSUSED */
        !          2203: gettimeofday (tp, tzp)
        !          2204:      struct timeval *tp;
        !          2205:      struct timezone *tzp;
        !          2206: {
        !          2207:   extern long time ();
        !          2208: 
        !          2209:   tp->tv_sec = time ((long *)0);    
        !          2210:   tp->tv_usec = 0;
        !          2211: }
        !          2212:  
        !          2213: #endif
        !          2214: #endif
        !          2215: #endif /* subprocess && !HAVE_GETTIMEOFDAY && HAVE_TIMEVAL */
        !          2216:   
        !          2217: /*
        !          2218:  *     This function will go away as soon as all the stubs fixed. (fnf)
        !          2219:  */
        !          2220: 
        !          2221: croak (badfunc)
        !          2222:      char *badfunc;
        !          2223: {
        !          2224:   printf ("%s not yet implemented\r\n", badfunc);
        !          2225:   reset_sys_modes ();
        !          2226:   exit (1);
        !          2227: }
        !          2228: 
        !          2229: #endif /* USG */
        !          2230: 
        !          2231: /* Directory routines for systems that don't have them. */
        !          2232: 
        !          2233: #ifdef SYSV_SYSTEM_DIR
        !          2234: 
        !          2235: #include <dirent.h>
        !          2236: 
        !          2237: #ifndef HAVE_CLOSEDIR
        !          2238: int
        !          2239: closedir (dirp)
        !          2240:      register DIR *dirp;              /* stream from opendir() */
        !          2241: {
        !          2242:   sys_close (dirp->dd_fd);
        !          2243:   free ((char *) dirp->dd_buf);       /* directory block defined in <dirent.h> */
        !          2244:   free ((char *) dirp);
        !          2245: }
        !          2246: #endif /* not HAVE_CLOSEDIR */
        !          2247: 
        !          2248: #endif /* SYSV_SYSTEM_DIR */
        !          2249: 
        !          2250: #ifdef NONSYSTEM_DIR_LIBRARY
        !          2251: 
        !          2252: DIR *
        !          2253: opendir (filename)
        !          2254:      char *filename;   /* name of directory */
        !          2255: {
        !          2256:   register DIR *dirp;          /* -> malloc'ed storage */
        !          2257:   register int fd;             /* file descriptor for read */
        !          2258:   struct stat sbuf;            /* result of fstat() */
        !          2259: 
        !          2260:   fd = sys_open (filename, 0);
        !          2261:   if (fd < 0)
        !          2262:     return 0;
        !          2263: 
        !          2264:   if (fstat (fd, &sbuf) < 0
        !          2265:       || (sbuf.st_mode & S_IFMT) != S_IFDIR
        !          2266:       || (dirp = (DIR *) malloc (sizeof (DIR))) == 0)
        !          2267:     {
        !          2268:       sys_close (fd);
        !          2269:       return 0;                /* bad luck today */
        !          2270:     }
        !          2271: 
        !          2272:   dirp->dd_fd = fd;
        !          2273:   dirp->dd_loc = dirp->dd_size = 0;    /* refill needed */
        !          2274: 
        !          2275:   return dirp;
        !          2276: }
        !          2277: 
        !          2278: void
        !          2279: closedir (dirp)
        !          2280:      register DIR *dirp;               /* stream from opendir() */
        !          2281: {
        !          2282:   sys_close (dirp->dd_fd);
        !          2283:   free ((char *) dirp);
        !          2284: }
        !          2285: 
        !          2286: 
        !          2287: #ifndef VMS
        !          2288: #define DIRSIZ 14
        !          2289: struct olddir
        !          2290:   {
        !          2291:     ino_t od_ino;              /* inode */
        !          2292:     char od_name[DIRSIZ];      /* filename */
        !          2293:   };
        !          2294: #endif /* not VMS */
        !          2295: 
        !          2296: struct direct dir_static;      /* simulated directory contents */
        !          2297: 
        !          2298: /* ARGUSED */
        !          2299: struct direct *
        !          2300: readdir (dirp)
        !          2301:      register DIR *dirp;       /* stream from opendir() */
        !          2302: {
        !          2303: #ifndef VMS
        !          2304:   register struct olddir *dp;  /* -> directory data */
        !          2305: #else /* VMS */
        !          2306:   register struct dir$_name *dp; /* -> directory data */
        !          2307:   register struct dir$_version *dv; /* -> version data */
        !          2308: #endif /* VMS */
        !          2309: 
        !          2310:   for (; ;)
        !          2311:     {
        !          2312:       if (dirp->dd_loc >= dirp->dd_size)
        !          2313:        dirp->dd_loc = dirp->dd_size = 0;
        !          2314: 
        !          2315:       if (dirp->dd_size == 0   /* refill buffer */
        !          2316:          && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
        !          2317:        return 0;
        !          2318: 
        !          2319: #ifndef VMS
        !          2320:       dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
        !          2321:       dirp->dd_loc += sizeof (struct olddir);
        !          2322: 
        !          2323:       if (dp->od_ino != 0)     /* not deleted entry */
        !          2324:        {
        !          2325:          dir_static.d_ino = dp->od_ino;
        !          2326:          strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
        !          2327:          dir_static.d_name[DIRSIZ] = '\0';
        !          2328:          dir_static.d_namlen = strlen (dir_static.d_name);
        !          2329:          dir_static.d_reclen = sizeof (struct direct)
        !          2330:            - MAXNAMLEN + 3
        !          2331:              + dir_static.d_namlen - dir_static.d_namlen % 4;
        !          2332:          return &dir_static;   /* -> simulated structure */
        !          2333:        }
        !          2334: #else /* VMS */
        !          2335:       dp = (struct dir$_name *) dirp->dd_buf;
        !          2336:       if (dirp->dd_loc == 0)
        !          2337:        dirp->dd_loc = (dp->dir$b_namecount&1) ? dp->dir$b_namecount + 1
        !          2338:          : dp->dir$b_namecount;
        !          2339:       dv = (struct dir$_version *)&dp->dir$t_name[dirp->dd_loc];
        !          2340:       dir_static.d_ino = dv->dir$w_fid_num;
        !          2341:       dir_static.d_namlen = dp->dir$b_namecount;
        !          2342:       dir_static.d_reclen = sizeof (struct direct)
        !          2343:        - MAXNAMLEN + 3
        !          2344:          + dir_static.d_namlen - dir_static.d_namlen % 4;
        !          2345:       strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
        !          2346:       dir_static.d_name[dir_static.d_namlen] = '\0';
        !          2347:       dirp->dd_loc = dirp->dd_size; /* only one record at a time */
        !          2348:       return &dir_static;
        !          2349: #endif /* VMS */
        !          2350:     }
        !          2351: }
        !          2352: 
        !          2353: #ifdef VMS
        !          2354: /* readdirver is just like readdir except it returns all versions of a file
        !          2355:    as separate entries.  */
        !          2356: 
        !          2357: /* ARGUSED */
        !          2358: struct direct *
        !          2359: readdirver (dirp)
        !          2360:      register DIR *dirp;       /* stream from opendir() */
        !          2361: {
        !          2362:   register struct dir$_name *dp; /* -> directory data */
        !          2363:   register struct dir$_version *dv; /* -> version data */
        !          2364: 
        !          2365:   if (dirp->dd_loc >= dirp->dd_size - sizeof (struct dir$_name))
        !          2366:     dirp->dd_loc = dirp->dd_size = 0;
        !          2367: 
        !          2368:   if (dirp->dd_size == 0       /* refill buffer */
        !          2369:       && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
        !          2370:     return 0;
        !          2371: 
        !          2372:   dp = (struct dir$_name *) dirp->dd_buf;
        !          2373:   if (dirp->dd_loc == 0)
        !          2374:     dirp->dd_loc = (dp->dir$b_namecount & 1) ? dp->dir$b_namecount + 1
        !          2375:                   : dp->dir$b_namecount;
        !          2376:   dv = (struct dir$_version *) &dp->dir$t_name[dirp->dd_loc];
        !          2377:   strncpy (dir_static.d_name, dp->dir$t_name, dp->dir$b_namecount);
        !          2378:   sprintf (&dir_static.d_name[dp->dir$b_namecount], ";%d", dv->dir$w_version);
        !          2379:   dir_static.d_namlen = strlen (dir_static.d_name);
        !          2380:   dir_static.d_ino = dv->dir$w_fid_num;
        !          2381:   dir_static.d_reclen = sizeof (struct direct) - MAXNAMLEN + 3
        !          2382:                        + dir_static.d_namlen - dir_static.d_namlen % 4;
        !          2383:   dirp->dd_loc = ((char *) (++dv) - dp->dir$t_name);
        !          2384:   return &dir_static;
        !          2385: }
        !          2386: 
        !          2387: #endif /* VMS */
        !          2388: 
        !          2389: #endif /* NONSYSTEM_DIR_LIBRARY */
        !          2390: 
        !          2391: /* Functions for VMS */
        !          2392: #ifdef VMS
        !          2393: #include <pwd.h>
        !          2394: #include <acldef.h>
        !          2395: #include <chpdef.h>
        !          2396: #include <jpidef.h>
        !          2397: 
        !          2398: /* Return as a string the VMS error string pertaining to STATUS.
        !          2399:    Reuses the same static buffer each time it is called.  */
        !          2400: 
        !          2401: char *
        !          2402: vmserrstr (status)
        !          2403:      int status;               /* VMS status code */
        !          2404: {
        !          2405:   int bufadr[2];
        !          2406:   short len;
        !          2407:   static char buf[257];
        !          2408: 
        !          2409:   bufadr[0] = sizeof buf - 1;
        !          2410:   bufadr[1] = buf;
        !          2411:   if (! (SYS$GETMSG (status, &len, bufadr, 0x1, 0) & 1))
        !          2412:     return "untranslatable VMS error status";
        !          2413:   buf[len] = '\0';
        !          2414:   return buf;
        !          2415: }
        !          2416: 
        !          2417: #ifdef access
        !          2418: #undef access
        !          2419:   
        !          2420: /* The following is necessary because 'access' emulation by VMS C (2.0) does
        !          2421:  * not work correctly.  (It also doesn't work well in version 2.3.)
        !          2422:  */
        !          2423: 
        !          2424: #ifdef VMS4_4
        !          2425: 
        !          2426: #define DESCRIPTOR(name,string) struct dsc$descriptor_s name = \
        !          2427:        { strlen(string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string }
        !          2428: 
        !          2429: typedef union {
        !          2430:     struct {
        !          2431:        unsigned short s_buflen;
        !          2432:        unsigned short s_code;
        !          2433:        char *s_bufadr;
        !          2434:        unsigned short *s_retlenadr;
        !          2435:     } s;
        !          2436:     int end;
        !          2437: } item;
        !          2438: #define buflen s.s_buflen
        !          2439: #define code s.s_code
        !          2440: #define bufadr s.s_bufadr
        !          2441: #define retlenadr s.s_retlenadr
        !          2442: 
        !          2443: #define R_OK 4 /* test for read permission */
        !          2444: #define W_OK 2 /* test for write permission */
        !          2445: #define X_OK 1 /* test for execute (search) permission */
        !          2446: #define F_OK 0 /* test for presence of file */
        !          2447: 
        !          2448: int
        !          2449: sys_access (path, mode)
        !          2450:      char *path;
        !          2451:      int mode;
        !          2452: {
        !          2453:   static char *user = NULL;
        !          2454:   char dir_fn[512];
        !          2455: 
        !          2456:   /* translate possible directory spec into .DIR file name, so brain-dead
        !          2457:    * access() can treat the directory like a file.  */
        !          2458:   if (directory_file_name (path, dir_fn))
        !          2459:     path = dir_fn;
        !          2460:   
        !          2461:   if (mode == F_OK)
        !          2462:     return access (path, mode);
        !          2463:   if (user == NULL && (user = getenv ("USER")) == NULL)
        !          2464:     return -1;
        !          2465:   {
        !          2466:        int stat;
        !          2467:        int flags;
        !          2468:        int acces;
        !          2469:        int dummy;
        !          2470:        item itemlst[3];
        !          2471:        DESCRIPTOR(path_desc, path);
        !          2472:        DESCRIPTOR(user_desc, user);
        !          2473:  
        !          2474:        flags = 0;
        !          2475:        acces = 0;
        !          2476:        if ((mode & X_OK) && ((stat = access(path, mode)) < 0 || mode == X_OK))
        !          2477:            return stat;
        !          2478:        if (mode & R_OK)
        !          2479:            acces |= CHP$M_READ;
        !          2480:        if (mode & W_OK)
        !          2481:            acces |= CHP$M_WRITE;
        !          2482:        itemlst[0].buflen = sizeof (int);
        !          2483:        itemlst[0].code = CHP$_FLAGS;
        !          2484:        itemlst[0].bufadr = &flags;
        !          2485:        itemlst[0].retlenadr = &dummy;
        !          2486:        itemlst[1].buflen = sizeof (int);
        !          2487:        itemlst[1].code = CHP$_ACCESS;
        !          2488:        itemlst[1].bufadr = &acces;
        !          2489:        itemlst[1].retlenadr = &dummy;
        !          2490:        itemlst[2].end = CHP$_END;
        !          2491:        stat = SYS$CHECK_ACCESS(&ACL$C_FILE, &path_desc, &user_desc, itemlst);
        !          2492:        return stat == SS$_NORMAL ? 0 : -1;
        !          2493:     }
        !          2494: }
        !          2495: 
        !          2496: #else /* not VMS4_4 */
        !          2497: 
        !          2498: #include <prvdef.h>
        !          2499: #define        ACE$M_WRITE     2
        !          2500: #define        ACE$C_KEYID     1
        !          2501: 
        !          2502: static unsigned short memid, grpid;
        !          2503: static unsigned int uic;
        !          2504: 
        !          2505: /* Called from init_sys_modes, so it happens not very often
        !          2506:    but at least each time Emacs is loaded.  */
        !          2507: sys_access_reinit ()
        !          2508: {
        !          2509:   uic = 0;
        !          2510: }
        !          2511: 
        !          2512: int
        !          2513: sys_access (filename, type)
        !          2514:      char * filename;
        !          2515:      int type;
        !          2516: {
        !          2517:   struct FAB fab;
        !          2518:   struct XABPRO xab;
        !          2519:   int status, prvmask[2], size, i, typecode, acl_controlled;
        !          2520:   unsigned int *aclptr, *aclend, aclbuf[60];
        !          2521: 
        !          2522:   /* Get UIC and GRP values for protection checking.  */
        !          2523:   if (uic == 0)
        !          2524:     {
        !          2525:       status = LIB$GETJPI (&JPI$_UIC, 0, 0, &uic, 0, 0);
        !          2526:       if (! (status & 1))
        !          2527:        return -1;
        !          2528:       memid = uic & 0xFFFF;
        !          2529:       grpid = uic >> 16;
        !          2530:     }
        !          2531: 
        !          2532:   if (type != 2)               /* not checking write access */
        !          2533:     return access (filename, type);
        !          2534: 
        !          2535:   /* Check write protection. */
        !          2536:     
        !          2537: #define        CHECKPRIV(bit)    (prvmask[bit / 32] & (1 << (bit % 32)))
        !          2538: #define        WRITEABLE(field)  (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE))
        !          2539: 
        !          2540:   /* Find privilege bits */
        !          2541:   status = sys$setprv (0, 0, 0, prvmask);
        !          2542:   if (! (status & 1))
        !          2543:     error ("Unable to find privileges: %s", vmserrstr (status));
        !          2544:   if (CHECKPRIV (PRV$V_BYPASS))
        !          2545:     return 0;                  /* BYPASS enabled */
        !          2546:   fab = cc$rms_fab;
        !          2547:   fab.fab$b_fac = FAB$M_GET;
        !          2548:   fab.fab$l_fna = filename;
        !          2549:   fab.fab$b_fns = strlen (filename);
        !          2550:   fab.fab$l_xab = &xab;
        !          2551:   xab = cc$rms_xabpro;
        !          2552:   xab.xab$l_aclbuf = aclbuf;
        !          2553:   xab.xab$w_aclsiz = sizeof (aclbuf);
        !          2554:   status = sys$open (&fab, 0, 0);
        !          2555:   if (! (status & 1))
        !          2556:     return -1;
        !          2557:   sys$close (&fab, 0, 0);
        !          2558:   /* Check system access */
        !          2559:   if (CHECKPRIV (PRV$V_SYSPRV) && WRITEABLE (XAB$V_SYS))
        !          2560:     return 0;
        !          2561:   /* Check ACL entries, if any */
        !          2562:   acl_controlled = 0;
        !          2563:   if (xab.xab$w_acllen > 0)
        !          2564:     {
        !          2565:       aclptr = aclbuf;
        !          2566:       aclend = &aclbuf[xab.xab$w_acllen / 4];
        !          2567:       while (*aclptr && aclptr < aclend)
        !          2568:        {
        !          2569:          size = (*aclptr & 0xff) / 4;
        !          2570:          typecode = (*aclptr >> 8) & 0xff;
        !          2571:          if (typecode == ACE$C_KEYID)
        !          2572:            for (i = size - 1; i > 1; i--)
        !          2573:              if (aclptr[i] == uic)
        !          2574:                {
        !          2575:                  acl_controlled = 1;
        !          2576:                  if (aclptr[1] & ACE$M_WRITE)
        !          2577:                    return 0;   /* Write access through ACL */
        !          2578:                }
        !          2579:          aclptr = &aclptr[size];
        !          2580:        }
        !          2581:       if (acl_controlled)      /* ACL specified, prohibits write access */
        !          2582:        return -1;
        !          2583:     }
        !          2584:   /* No ACL entries specified, check normal protection */
        !          2585:   if (WRITEABLE (XAB$V_WLD))   /* World writeable */
        !          2586:     return 0;
        !          2587:   if (WRITEABLE (XAB$V_GRP) &&
        !          2588:       (unsigned short) (xab.xab$l_uic >> 16) == grpid)
        !          2589:     return 0;                  /* Group writeable */
        !          2590:   if (WRITEABLE (XAB$V_OWN) &&
        !          2591:       (xab.xab$l_uic & 0xFFFF) == memid)
        !          2592:     return 0;                  /* Owner writeable */
        !          2593: 
        !          2594:   return -1;   /* Not writeable */
        !          2595: }
        !          2596: #endif /* not VMS4_4 */
        !          2597: #endif /* access */
        !          2598:   
        !          2599: static char vtbuf[NAM$C_MAXRSS+1];
        !          2600: 
        !          2601: /* translate a vms file spec to a unix path */
        !          2602: char *
        !          2603: sys_translate_vms (vfile)
        !          2604:      char * vfile;
        !          2605: {
        !          2606:   char * p;
        !          2607:   char * targ;
        !          2608: 
        !          2609:   if (!vfile)
        !          2610:     return 0;
        !          2611: 
        !          2612:   targ = vtbuf;
        !          2613: 
        !          2614:   /* leading device or logical name is a root directory */
        !          2615:   if (p = strchr (vfile, ':'))
        !          2616:     {
        !          2617:       *targ++ = '/';
        !          2618:       while (vfile < p)
        !          2619:        *targ++ = *vfile++;
        !          2620:       vfile++;
        !          2621:       *targ++ = '/';
        !          2622:     }
        !          2623:   p = vfile;
        !          2624:   if (*p == '[' || *p == '<')
        !          2625:     {
        !          2626:       while (*++vfile != *p + 2)
        !          2627:        switch (*vfile)
        !          2628:          {
        !          2629:          case '.':
        !          2630:            if (vfile[-1] == *p)
        !          2631:              *targ++ = '.';
        !          2632:            *targ++ = '/';
        !          2633:            break;
        !          2634: 
        !          2635:          case '-':
        !          2636:            *targ++ = '.';
        !          2637:            *targ++ = '.';
        !          2638:            break;
        !          2639:            
        !          2640:          default:
        !          2641:            *targ++ = *vfile;
        !          2642:            break;
        !          2643:          }
        !          2644:       vfile++;
        !          2645:       *targ++ = '/';
        !          2646:     }
        !          2647:   while (*vfile)
        !          2648:     *targ++ = *vfile++;
        !          2649: 
        !          2650:   return vtbuf;
        !          2651: }
        !          2652: 
        !          2653: static char utbuf[NAM$C_MAXRSS+1];
        !          2654: 
        !          2655: /* translate a unix path to a VMS file spec */
        !          2656: char *
        !          2657: sys_translate_unix (ufile)
        !          2658:      char * ufile;
        !          2659: {
        !          2660:   int slash_seen = 0;
        !          2661:   char *p;
        !          2662:   char * targ;
        !          2663: 
        !          2664:   if (!ufile)
        !          2665:     return 0;
        !          2666: 
        !          2667:   targ = utbuf;
        !          2668: 
        !          2669:   if (*ufile == '/')
        !          2670:     {
        !          2671:       ufile++;
        !          2672:     }
        !          2673: 
        !          2674:   while (*ufile)
        !          2675:     {
        !          2676:       switch (*ufile)
        !          2677:        {
        !          2678:        case '/':
        !          2679:          if (slash_seen)
        !          2680:            if (index (&ufile[1], '/'))
        !          2681:              *targ++ = '.';
        !          2682:            else
        !          2683:              *targ++ = ']';
        !          2684:          else
        !          2685:            {
        !          2686:              *targ++ = ':';
        !          2687:              if (index (&ufile[1], '/'))
        !          2688:                *targ++ = '[';
        !          2689:              slash_seen = 1;
        !          2690:            }
        !          2691:          break;
        !          2692: 
        !          2693:        case '.':
        !          2694:          if (strncmp (ufile, "./", 2) == 0)
        !          2695:            {
        !          2696:              if (!slash_seen)
        !          2697:                {
        !          2698:                  *targ++ = '[';
        !          2699:                  slash_seen = 1;
        !          2700:                }
        !          2701:              ufile++;          /* skip the dot */
        !          2702:              if (index (&ufile[1], '/'))
        !          2703:                *targ++ = '.';
        !          2704:              else
        !          2705:                *targ++ = ']';
        !          2706:            }
        !          2707:          else if (strncmp (ufile, "../", 3) == 0)
        !          2708:            {
        !          2709:              if (!slash_seen)
        !          2710:                {
        !          2711:                  *targ++ = '[';
        !          2712:                  slash_seen = 1;
        !          2713:                }
        !          2714:              *targ++ = '-';
        !          2715:              ufile += 2;       /* skip the dots */
        !          2716:              if (index (&ufile[1], '/'))
        !          2717:                *targ++ = '.';
        !          2718:              else
        !          2719:                *targ++ = ']';
        !          2720:            }
        !          2721:          else
        !          2722:            *targ++ = *ufile;
        !          2723:          break;
        !          2724: 
        !          2725:        default:
        !          2726:          *targ++ = *ufile;
        !          2727:          break;
        !          2728:        }
        !          2729:       ufile++;
        !          2730:     }
        !          2731:   *targ = '\0';
        !          2732:   
        !          2733:   return utbuf;
        !          2734: }
        !          2735: 
        !          2736: char *
        !          2737: getwd (pathname)
        !          2738:      char *pathname;
        !          2739: {
        !          2740:   char *ptr;
        !          2741:   strcpy (pathname, egetenv ("PATH"));
        !          2742: 
        !          2743:   ptr = pathname;
        !          2744:   while (*ptr)
        !          2745:     {
        !          2746:       if ('a' <= *ptr && *ptr <= 'z')
        !          2747:        *ptr -= 040;
        !          2748:       ptr++;
        !          2749:     }
        !          2750:   return pathname;
        !          2751: }
        !          2752: 
        !          2753: getppid ()
        !          2754: {
        !          2755:   long item_code = JPI$_OWNER;
        !          2756:   unsigned long parent_id;
        !          2757:   int status;
        !          2758: 
        !          2759:   if (((status = LIB$GETJPI (&item_code, 0, 0, &parent_id)) & 1) == 0)
        !          2760:     {
        !          2761:       errno = EVMSERR;
        !          2762:       vaxc$errno = status;
        !          2763:       return -1;
        !          2764:     }
        !          2765:   return parent_id;
        !          2766: }
        !          2767: 
        !          2768: #undef getuid
        !          2769: unsigned
        !          2770: sys_getuid ()
        !          2771: {
        !          2772:   return (getgid () << 16) | getuid ();
        !          2773: }
        !          2774: 
        !          2775: int
        !          2776: sys_read (fildes, buf, nbyte)
        !          2777:      int fildes;
        !          2778:      char *buf;
        !          2779:      unsigned int nbyte;
        !          2780: {
        !          2781:   return read (fildes, buf, (nbyte < MAXIOSIZE ? nbyte : MAXIOSIZE));
        !          2782: }
        !          2783: 
        !          2784: #if 0
        !          2785: int
        !          2786: sys_write (fildes, buf, nbyte)
        !          2787:      int fildes;
        !          2788:      char *buf;
        !          2789:      unsigned int nbyte;
        !          2790: {
        !          2791:   register int nwrote, rtnval = 0;
        !          2792: 
        !          2793:   while (nbyte > MAXIOSIZE && (nwrote = write (fildes, buf, MAXIOSIZE)) > 0) {
        !          2794:     nbyte -= nwrote;
        !          2795:     buf += nwrote;
        !          2796:     rtnval += nwrote;
        !          2797:   }
        !          2798:   if (nwrote < 0)
        !          2799:     return rtnval ? rtnval : -1;
        !          2800:   if ((nwrote = write (fildes, buf, nbyte)) < 0)
        !          2801:     return rtnval ? rtnval : -1;
        !          2802:   return (rtnval + nwrote);
        !          2803: }
        !          2804: #endif /* 0 */
        !          2805: 
        !          2806: /*
        !          2807:  *     VAX/VMS VAX C RTL really loses. It insists that records
        !          2808:  *      end with a newline (carriage return) character, and if they
        !          2809:  *     don't it adds one (nice of it isn't it!)
        !          2810:  *
        !          2811:  *     Thus we do this stupidity below.
        !          2812:  */
        !          2813: 
        !          2814: int
        !          2815: sys_write (fildes, buf, nbytes)
        !          2816:      int fildes;
        !          2817:      char *buf;
        !          2818:      unsigned int nbytes;
        !          2819: {
        !          2820:   register char *p;
        !          2821:   register char *e;
        !          2822:   int retval, sum;
        !          2823:   p = buf;
        !          2824:   sum = 0;
        !          2825:   while (nbytes > 0)
        !          2826:     {
        !          2827:       e =  p + min (MAXIOSIZE, nbytes) - 1;
        !          2828:       while (*e != '\n' && e > p) e--;
        !          2829:       if (p == e)              /* Ok.. so here we add a newline... sigh. */
        !          2830:        e = p + min (MAXIOSIZE, nbytes) - 1;
        !          2831:       retval = write (fildes, p, e - p + 1);
        !          2832:       if (retval != e - p + 1) return -1;
        !          2833:       p = e + 1;
        !          2834:       sum = sum + retval;
        !          2835:       nbytes -= retval;
        !          2836:     }
        !          2837:   return sum;
        !          2838: }
        !          2839: 
        !          2840: /* Create file NEW copying its attributes from file OLD.  If
        !          2841:    OLD is 0 or does not exist, create based on the value of
        !          2842:    vms_stmlf_recfm. */
        !          2843: 
        !          2844: int
        !          2845: creat_copy_attrs (old, new)
        !          2846:      char *old, *new;
        !          2847: {
        !          2848:   struct FAB fab = cc$rms_fab;
        !          2849:   struct XABPRO xabpro;
        !          2850:   char aclbuf[256];    /* Choice of size is arbitrary.  See below. */
        !          2851:   extern int vms_stmlf_recfm;
        !          2852: 
        !          2853:   if (old)
        !          2854:     {
        !          2855:       fab.fab$b_fac = FAB$M_GET;
        !          2856:       fab.fab$l_fna = old;
        !          2857:       fab.fab$b_fns = strlen (old);
        !          2858:       fab.fab$l_xab = &xabpro;
        !          2859:       xabpro = cc$rms_xabpro;
        !          2860:       xabpro.xab$l_aclbuf = aclbuf;
        !          2861:       xabpro.xab$w_aclsiz = sizeof aclbuf;
        !          2862:       /* Call $OPEN to fill in the fab & xabpro fields. */
        !          2863:       if (sys$open (&fab, 0, 0) & 1)
        !          2864:        {
        !          2865:          sys$close (&fab, 0, 0);
        !          2866:          fab.fab$l_alq = 0;    /* zero the allocation quantity */
        !          2867:          if (xabpro.xab$w_acllen > 0)
        !          2868:            {
        !          2869:              if (xabpro.xab$w_acllen > sizeof aclbuf)
        !          2870:                /* If the acl buffer was too short, redo open with longer one.
        !          2871:                   Wouldn't need to do this if there were some system imposed
        !          2872:                   limit on the size of an ACL, but I can't find any such. */
        !          2873:                {
        !          2874:                  xabpro.xab$l_aclbuf = alloca (xabpro.xab$w_acllen);
        !          2875:                  xabpro.xab$w_aclsiz = xabpro.xab$w_acllen;
        !          2876:                  if (sys$open (&fab, 0, 0) & 1)
        !          2877:                    sys$close (&fab, 0, 0);
        !          2878:                  else
        !          2879:                    old = 0;
        !          2880:                }
        !          2881:            }
        !          2882:          else
        !          2883:            xabpro.xab$l_aclbuf = 0;
        !          2884:        }
        !          2885:       else
        !          2886:        old = 0;
        !          2887:     }
        !          2888:   fab.fab$l_fna = new;
        !          2889:   fab.fab$b_fns = strlen (new);
        !          2890:   if (!old)
        !          2891:     {
        !          2892:       fab.fab$l_xab = 0;
        !          2893:       fab.fab$b_rfm = vms_stmlf_recfm ? FAB$C_STMLF : FAB$C_VAR;
        !          2894:       fab.fab$b_rat = FAB$M_CR;
        !          2895:     }
        !          2896:   /* Create the new file with either default attrs or attrs copied
        !          2897:      from old file. */
        !          2898:   if (!(SYS$CREATE (&fab, 0, 0) & 1))
        !          2899:     return -1;
        !          2900:   sys$close (&fab, 0, 0);
        !          2901:   /* As this is a "replacement" for creat, return a file descriptor
        !          2902:      opened for writing. */
        !          2903:   return open (new, O_WRONLY);
        !          2904: }
        !          2905: 
        !          2906: #ifdef creat
        !          2907: #undef creat
        !          2908: #include <varargs.h>
        !          2909: 
        !          2910: sys_creat (va_alist)
        !          2911:      va_dcl
        !          2912: {
        !          2913:   va_list list_incrementor;
        !          2914:   char *name;
        !          2915:   int mode;
        !          2916:   int rfd;                     /* related file descriptor */
        !          2917:   int fd;                      /* Our new file descriptor */
        !          2918:   int count;
        !          2919:   struct stat st_buf;
        !          2920:   char rfm[12];
        !          2921:   char rat[15];
        !          2922:   char mrs[13];
        !          2923:   char fsz[13];
        !          2924:   extern int vms_stmlf_recfm;
        !          2925: 
        !          2926:   va_count (count);
        !          2927:   va_start (list_incrementor);
        !          2928:   name = va_arg (list_incrementor, char *);
        !          2929:   mode = va_arg (list_incrementor, int);
        !          2930:   if (count > 2)
        !          2931:     rfd = va_arg (list_incrementor, int);
        !          2932:   va_end (list_incrementor);
        !          2933:   if (count > 2)
        !          2934:     {
        !          2935:       /* Use information from the related file descriptor to set record
        !          2936:         format of the newly created file. */
        !          2937:       fstat (rfd, &st_buf);
        !          2938:       switch (st_buf.st_fab_rfm)
        !          2939:        {
        !          2940:        case FAB$C_FIX:
        !          2941:          strcpy (rfm, "rfm = fix");
        !          2942:          sprintf (mrs, "mrs = %d", st_buf.st_fab_mrs);
        !          2943:          strcpy (rat, "rat = ");
        !          2944:          if (st_buf.st_fab_rat & FAB$M_CR)
        !          2945:            strcat (rat, "cr");
        !          2946:          else if (st_buf.st_fab_rat & FAB$M_FTN)
        !          2947:            strcat (rat, "ftn");
        !          2948:          else if (st_buf.st_fab_rat & FAB$M_PRN)
        !          2949:            strcat (rat, "prn");
        !          2950:          if (st_buf.st_fab_rat & FAB$M_BLK)
        !          2951:            if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
        !          2952:              strcat (rat, ", blk");
        !          2953:            else
        !          2954:              strcat (rat, "blk");
        !          2955:          return creat (name, 0, rfm, rat, mrs);
        !          2956: 
        !          2957:        case FAB$C_VFC:
        !          2958:          strcpy (rfm, "rfm = vfc");
        !          2959:          sprintf (fsz, "fsz = %d", st_buf.st_fab_fsz);
        !          2960:          strcpy (rat, "rat = ");
        !          2961:          if (st_buf.st_fab_rat & FAB$M_CR)
        !          2962:            strcat (rat, "cr");
        !          2963:          else if (st_buf.st_fab_rat & FAB$M_FTN)
        !          2964:            strcat (rat, "ftn");
        !          2965:          else if (st_buf.st_fab_rat & FAB$M_PRN)
        !          2966:            strcat (rat, "prn");
        !          2967:          if (st_buf.st_fab_rat & FAB$M_BLK)
        !          2968:            if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
        !          2969:              strcat (rat, ", blk");
        !          2970:            else
        !          2971:              strcat (rat, "blk");
        !          2972:          return creat (name, 0, rfm, rat, fsz);
        !          2973: 
        !          2974:        case FAB$C_STM:
        !          2975:          strcpy (rfm, "rfm = stm");
        !          2976:          break;
        !          2977: 
        !          2978:        case FAB$C_STMCR:
        !          2979:          strcpy (rfm, "rfm = stmcr");
        !          2980:          break;
        !          2981: 
        !          2982:        case FAB$C_STMLF:
        !          2983:          strcpy (rfm, "rfm = stmlf");
        !          2984:          break;
        !          2985: 
        !          2986:        case FAB$C_UDF:
        !          2987:          strcpy (rfm, "rfm = udf");
        !          2988:          break;
        !          2989: 
        !          2990:        case FAB$C_VAR:
        !          2991:          strcpy (rfm, "rfm = var");
        !          2992:          break;
        !          2993:        }
        !          2994:       strcpy (rat, "rat = ");
        !          2995:       if (st_buf.st_fab_rat & FAB$M_CR)
        !          2996:        strcat (rat, "cr");
        !          2997:       else if (st_buf.st_fab_rat & FAB$M_FTN)
        !          2998:        strcat (rat, "ftn");
        !          2999:       else if (st_buf.st_fab_rat & FAB$M_PRN)
        !          3000:        strcat (rat, "prn");
        !          3001:       if (st_buf.st_fab_rat & FAB$M_BLK)
        !          3002:        if (st_buf.st_fab_rat & (FAB$M_CR|FAB$M_FTN|FAB$M_PRN))
        !          3003:          strcat (rat, ", blk");
        !          3004:        else
        !          3005:          strcat (rat, "blk");
        !          3006:     }
        !          3007:   else
        !          3008:     {
        !          3009:       strcpy (rfm, vms_stmlf_recfm ? "rfm = stmlf" : "rfm=var");
        !          3010:       strcpy (rat, "rat=cr");
        !          3011:     }
        !          3012:   /* Until the VAX C RTL fixes the many bugs with modes, always use
        !          3013:      mode 0 to get the user's default protection. */
        !          3014:   fd = creat (name, 0, rfm, rat);
        !          3015:   if (fd < 0 && errno == EEXIST)
        !          3016:     {
        !          3017:       if (unlink (name) < 0)
        !          3018:        report_file_error ("delete", build_string (name));
        !          3019:       fd = creat (name, 0, rfm, rat);
        !          3020:     }
        !          3021:   return fd;
        !          3022: }
        !          3023: #endif /* creat */
        !          3024: 
        !          3025: /* fwrite to stdout is S L O W.  Speed it up by using fputc...*/
        !          3026: sys_fwrite (ptr, size, num, fp)
        !          3027:      register char * ptr;
        !          3028:      FILE * fp;
        !          3029: {
        !          3030:   register int tot = num * size;
        !          3031: 
        !          3032:   while (tot--)
        !          3033:     fputc (*ptr++, fp);
        !          3034: }
        !          3035: 
        !          3036: /*
        !          3037:  * The VMS C library routine creat() actually creates a new version of an
        !          3038:  * existing file rather than truncating the old version.  There are times
        !          3039:  * when this is not the desired behavior, for instance, when writing an
        !          3040:  * auto save file (you only want one version), or when you don't have
        !          3041:  * write permission in the directory containing the file (but the file
        !          3042:  * itself is writable).  Hence this routine, which is equivalent to 
        !          3043:  * "close (creat (fn, 0));" on Unix if fn already exists.
        !          3044:  */
        !          3045: int
        !          3046: vms_truncate (fn)
        !          3047:      char *fn;
        !          3048: {
        !          3049:   struct FAB xfab = cc$rms_fab;
        !          3050:   struct RAB xrab = cc$rms_rab;
        !          3051:   int status;
        !          3052: 
        !          3053:   xfab.fab$l_fop = FAB$M_TEF;  /* free allocated but unused blocks on close */
        !          3054:   xfab.fab$b_fac = FAB$M_TRN | FAB$M_GET; /* allow truncate and get access */
        !          3055:   xfab.fab$b_shr = FAB$M_NIL;  /* allow no sharing - file must be locked */
        !          3056:   xfab.fab$l_fna = fn;
        !          3057:   xfab.fab$b_fns = strlen (fn);
        !          3058:   xfab.fab$l_dna = ";0";       /* default to latest version of the file */
        !          3059:   xfab.fab$b_dns = 2;
        !          3060:   xrab.rab$l_fab = &xfab;
        !          3061: 
        !          3062:   /* This gibberish opens the file, positions to the first record, and
        !          3063:      deletes all records from there until the end of file. */
        !          3064:   if ((sys$open (&xfab) & 01) == 01)
        !          3065:     {
        !          3066:       if ((sys$connect (&xrab) & 01) == 01 &&
        !          3067:          (sys$find (&xrab) & 01) == 01 &&
        !          3068:          (sys$truncate (&xrab) & 01) == 01)
        !          3069:        status = 0;
        !          3070:       else
        !          3071:        status = -1;
        !          3072:     }
        !          3073:   else
        !          3074:     status = -1;
        !          3075:   sys$close (&xfab);
        !          3076:   return status;
        !          3077: }
        !          3078: 
        !          3079: /* Define this symbol to actually read SYSUAF.DAT.  This requires either
        !          3080:    SYSPRV or a readable SYSUAF.DAT. */
        !          3081: 
        !          3082: #ifdef READ_SYSUAF
        !          3083: /*
        !          3084:  * getuaf.c
        !          3085:  *
        !          3086:  * Routine to read the VMS User Authorization File and return
        !          3087:  * a specific user's record.
        !          3088:  */
        !          3089: 
        !          3090: static struct UAF retuaf;
        !          3091: 
        !          3092: struct UAF *
        !          3093: get_uaf_name(uname)
        !          3094:      char * uname;
        !          3095: {
        !          3096:   register status;
        !          3097:   struct FAB uaf_fab;
        !          3098:   struct RAB uaf_rab;
        !          3099:   
        !          3100:   uaf_fab = cc$rms_fab;
        !          3101:   uaf_rab = cc$rms_rab;
        !          3102:   /* initialize fab fields */
        !          3103:   uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
        !          3104:   uaf_fab.fab$b_fns = 21;
        !          3105:   uaf_fab.fab$b_fac = FAB$M_GET;
        !          3106:   uaf_fab.fab$b_org = FAB$C_IDX;
        !          3107:   uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
        !          3108:   /* initialize rab fields */
        !          3109:   uaf_rab.rab$l_fab = &uaf_fab;
        !          3110:   /* open the User Authorization File */
        !          3111:   status = sys$open(&uaf_fab);
        !          3112:   if (!(status&1))
        !          3113:     {
        !          3114:       errno = EVMSERR;
        !          3115:       vaxc$errno = status;
        !          3116:       return 0;
        !          3117:     }
        !          3118:   status = sys$connect(&uaf_rab);
        !          3119:   if (!(status&1))
        !          3120:     {
        !          3121:       errno = EVMSERR;
        !          3122:       vaxc$errno = status;
        !          3123:       return 0;
        !          3124:     }
        !          3125:   /* read the requested record - index is in uname */
        !          3126:   uaf_rab.rab$l_kbf = uname;
        !          3127:   uaf_rab.rab$b_ksz = strlen (uname);
        !          3128:   uaf_rab.rab$b_rac = RAB$C_KEY;
        !          3129:   uaf_rab.rab$l_ubf = (char *)&retuaf;
        !          3130:   uaf_rab.rab$w_usz = sizeof retuaf;
        !          3131:   status = sys$get(&uaf_rab);
        !          3132:   if (!(status&1))
        !          3133:     {
        !          3134:       errno = EVMSERR;
        !          3135:       vaxc$errno = status;
        !          3136:       return 0;
        !          3137:     }
        !          3138:   /* close the User Authorization File */
        !          3139:   status = sys$disconnect(&uaf_rab);
        !          3140:   if (!(status&1))
        !          3141:     {
        !          3142:       errno = EVMSERR;
        !          3143:       vaxc$errno = status;
        !          3144:       return 0;
        !          3145:     }
        !          3146:   status = sys$close(&uaf_fab);
        !          3147:   if (!(status&1))
        !          3148:     {
        !          3149:       errno = EVMSERR;
        !          3150:       vaxc$errno = status;
        !          3151:       return 0;
        !          3152:     }
        !          3153:   return &retuaf;
        !          3154: }
        !          3155: 
        !          3156: struct UAF *
        !          3157: get_uaf_uic(uic)
        !          3158:      unsigned long uic;
        !          3159: {
        !          3160:   register status;
        !          3161:   struct FAB uaf_fab;
        !          3162:   struct RAB uaf_rab;
        !          3163:   
        !          3164:   uaf_fab = cc$rms_fab;
        !          3165:   uaf_rab = cc$rms_rab;
        !          3166:   /* initialize fab fields */
        !          3167:   uaf_fab.fab$l_fna = "SYS$SYSTEM:SYSUAF.DAT";
        !          3168:   uaf_fab.fab$b_fns = 21;
        !          3169:   uaf_fab.fab$b_fac = FAB$M_GET;
        !          3170:   uaf_fab.fab$b_org = FAB$C_IDX;
        !          3171:   uaf_fab.fab$b_shr = FAB$M_GET|FAB$M_PUT|FAB$M_UPD|FAB$M_DEL;
        !          3172:   /* initialize rab fields */
        !          3173:   uaf_rab.rab$l_fab = &uaf_fab;
        !          3174:   /* open the User Authorization File */
        !          3175:   status = sys$open(&uaf_fab);
        !          3176:   if (!(status&1))
        !          3177:     {
        !          3178:       errno = EVMSERR;
        !          3179:       vaxc$errno = status;
        !          3180:       return 0;
        !          3181:     }
        !          3182:   status = sys$connect(&uaf_rab);
        !          3183:   if (!(status&1))
        !          3184:     {
        !          3185:       errno = EVMSERR;
        !          3186:       vaxc$errno = status;
        !          3187:       return 0;
        !          3188:     }
        !          3189:   /* read the requested record - index is in uic */
        !          3190:   uaf_rab.rab$b_krf = 1;       /* 1st alternate key */
        !          3191:   uaf_rab.rab$l_kbf = (char *) &uic;
        !          3192:   uaf_rab.rab$b_ksz = sizeof uic;
        !          3193:   uaf_rab.rab$b_rac = RAB$C_KEY;
        !          3194:   uaf_rab.rab$l_ubf = (char *)&retuaf;
        !          3195:   uaf_rab.rab$w_usz = sizeof retuaf;
        !          3196:   status = sys$get(&uaf_rab);
        !          3197:   if (!(status&1))
        !          3198:     {
        !          3199:       errno = EVMSERR;
        !          3200:       vaxc$errno = status;
        !          3201:       return 0;
        !          3202:     }
        !          3203:   /* close the User Authorization File */
        !          3204:   status = sys$disconnect(&uaf_rab);
        !          3205:   if (!(status&1))
        !          3206:     {
        !          3207:       errno = EVMSERR;
        !          3208:       vaxc$errno = status;
        !          3209:       return 0;
        !          3210:     }
        !          3211:   status = sys$close(&uaf_fab);
        !          3212:   if (!(status&1))
        !          3213:     {
        !          3214:       errno = EVMSERR;
        !          3215:       vaxc$errno = status;
        !          3216:       return 0;
        !          3217:     }
        !          3218:   return &retuaf;
        !          3219: }
        !          3220: 
        !          3221: static struct passwd retpw;
        !          3222: 
        !          3223: struct passwd *
        !          3224: cnv_uaf_pw (up)
        !          3225:      struct UAF * up;
        !          3226: {
        !          3227:   char * ptr;
        !          3228: 
        !          3229:   /* copy these out first because if the username is 32 chars, the next
        !          3230:      section will overwrite the first byte of the UIC */
        !          3231:   retpw.pw_uid = up->uaf$w_mem;
        !          3232:   retpw.pw_gid = up->uaf$w_grp;
        !          3233: 
        !          3234:   /* I suppose this is not the best sytle, to possibly overwrite one
        !          3235:      byte beyond the end of the field, but what the heck... */
        !          3236:   ptr = &up->uaf$t_username[UAF$S_USERNAME];
        !          3237:   while (ptr[-1] == ' ')
        !          3238:     ptr--;
        !          3239:   *ptr = '\0';
        !          3240:   strcpy (retpw.pw_name, up->uaf$t_username);
        !          3241: 
        !          3242:   /* the rest of these are counted ascii strings */
        !          3243:   strncpy (retpw.pw_gecos, &up->uaf$t_owner[1], up->uaf$t_owner[0]);
        !          3244:   retpw.pw_gecos[up->uaf$t_owner[0]] = '\0';
        !          3245:   strncpy (retpw.pw_dir, &up->uaf$t_defdev[1], up->uaf$t_defdev[0]);
        !          3246:   retpw.pw_dir[up->uaf$t_defdev[0]] = '\0';
        !          3247:   strncat (retpw.pw_dir, &up->uaf$t_defdir[1], up->uaf$t_defdir[0]);
        !          3248:   retpw.pw_dir[up->uaf$t_defdev[0] + up->uaf$t_defdir[0]] = '\0';
        !          3249:   strncpy (retpw.pw_shell, &up->uaf$t_defcli[1], up->uaf$t_defcli[0]);
        !          3250:   retpw.pw_shell[up->uaf$t_defcli[0]] = '\0';
        !          3251: 
        !          3252:   return &retpw;
        !          3253: }
        !          3254: #else /* not READ_SYSUAF */
        !          3255: static struct passwd retpw;
        !          3256: #endif /* not READ_SYSUAF */
        !          3257: 
        !          3258: struct passwd *
        !          3259: getpwnam (name)
        !          3260:      char * name;
        !          3261: {
        !          3262: #ifdef READ_SYSUAF
        !          3263:   struct UAF *up;
        !          3264: #else
        !          3265:   char * user;
        !          3266:   char * dir;
        !          3267:   char * full;
        !          3268: #endif /* READ_SYSUAF */
        !          3269:   char *ptr = name;
        !          3270: 
        !          3271:   while (*ptr)
        !          3272:     {
        !          3273:       if ('a' <= *ptr && *ptr <= 'z')
        !          3274:        *ptr -= 040;
        !          3275:       ptr++;
        !          3276:     }
        !          3277: #ifdef READ_SYSUAF
        !          3278:   if (!(up = get_uaf_name (name)))
        !          3279:     return 0;
        !          3280:   return cnv_uaf_pw (up);
        !          3281: #else
        !          3282:   if (strcmp (name, getenv ("USER")) == 0)
        !          3283:     {
        !          3284:       retpw.pw_uid = getuid ();
        !          3285:       retpw.pw_gid = getgid ();
        !          3286:       strcpy (retpw.pw_name, name);
        !          3287:       if (full = egetenv ("FULLNAME"))
        !          3288:        strcpy (retpw.pw_gecos, full);
        !          3289:       else
        !          3290:        *retpw.pw_gecos = '\0';
        !          3291:       strcpy (retpw.pw_dir, egetenv ("HOME"));
        !          3292:       *retpw.pw_shell = '\0';
        !          3293:       return &retpw;
        !          3294:     }
        !          3295:   else
        !          3296:     return 0;
        !          3297: #endif /* not READ_SYSUAF */
        !          3298: }
        !          3299: 
        !          3300: struct passwd *
        !          3301: getpwuid (uid)
        !          3302:      unsigned long uid;
        !          3303: {
        !          3304: #ifdef READ_SYSUAF
        !          3305:   struct UAF * up;
        !          3306: 
        !          3307:   if (!(up = get_uaf_uic (uid)))
        !          3308:     return 0;
        !          3309:   return cnv_uaf_pw (up);
        !          3310: #else
        !          3311:   if (uid == sys_getuid ())
        !          3312:     return getpwnam (egetenv ("USER"));
        !          3313:   else
        !          3314:     return 0;
        !          3315: #endif /* not READ_SYSUAF */
        !          3316: }
        !          3317: 
        !          3318: /* return total address space available to the current process.  This is
        !          3319:    the sum of the current p0 size, p1 size and free page table entries
        !          3320:    available. */
        !          3321: vlimit ()
        !          3322: {
        !          3323:   int item_code;
        !          3324:   unsigned long free_pages;
        !          3325:   unsigned long frep0va;
        !          3326:   unsigned long frep1va;
        !          3327:   register status;
        !          3328: 
        !          3329:   item_code = JPI$_FREPTECNT;
        !          3330:   if (((status = LIB$GETJPI (&item_code, 0, 0, &free_pages)) & 1) == 0)
        !          3331:     {
        !          3332:       errno = EVMSERR;
        !          3333:       vaxc$errno = status;
        !          3334:       return -1;
        !          3335:     }
        !          3336:   free_pages *= 512;
        !          3337: 
        !          3338:   item_code = JPI$_FREP0VA;
        !          3339:   if (((status = LIB$GETJPI (&item_code, 0, 0, &frep0va)) & 1) == 0)
        !          3340:     {
        !          3341:       errno = EVMSERR;
        !          3342:       vaxc$errno = status;
        !          3343:       return -1;
        !          3344:     }
        !          3345:   item_code = JPI$_FREP1VA;
        !          3346:   if (((status = LIB$GETJPI (&item_code, 0, 0, &frep1va)) & 1) == 0)
        !          3347:     {
        !          3348:       errno = EVMSERR;
        !          3349:       vaxc$errno = status;
        !          3350:       return -1;
        !          3351:     }
        !          3352: 
        !          3353:   return free_pages + frep0va + (0x7fffffff - frep1va);
        !          3354: }
        !          3355: 
        !          3356: define_logical_name (varname, string)
        !          3357:      char *varname;
        !          3358:      char *string;
        !          3359: {
        !          3360:   struct dsc$descriptor_s strdsc =
        !          3361:     {strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, string};
        !          3362:   struct dsc$descriptor_s envdsc =
        !          3363:     {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
        !          3364:   struct dsc$descriptor_s lnmdsc =
        !          3365:     {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
        !          3366: 
        !          3367:   return LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
        !          3368: }
        !          3369: 
        !          3370: delete_logical_name (varname)
        !          3371:      char *varname;
        !          3372: {
        !          3373:   struct dsc$descriptor_s envdsc =
        !          3374:     {strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
        !          3375:   struct dsc$descriptor_s lnmdsc =
        !          3376:     {7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
        !          3377: 
        !          3378:   return LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
        !          3379: }
        !          3380: 
        !          3381: ulimit()
        !          3382: {}
        !          3383: 
        !          3384: setpriority()
        !          3385: {}
        !          3386: 
        !          3387: setpgrp()
        !          3388: {}
        !          3389: 
        !          3390: execvp()
        !          3391: {
        !          3392:   error ("execvp system call not implemented");
        !          3393: }
        !          3394: 
        !          3395: int
        !          3396: rename (from, to)
        !          3397:      char *from, *to;
        !          3398: {
        !          3399:   int status;
        !          3400:   struct FAB from_fab = cc$rms_fab, to_fab = cc$rms_fab;
        !          3401:   struct NAM from_nam = cc$rms_nam, to_nam = cc$rms_nam;
        !          3402:   char from_esn[NAM$C_MAXRSS];
        !          3403:   char to_esn[NAM$C_MAXRSS];
        !          3404: 
        !          3405:   from_fab.fab$l_fna = from;
        !          3406:   from_fab.fab$b_fns = strlen (from);
        !          3407:   from_fab.fab$l_nam = &from_nam;
        !          3408:   from_fab.fab$l_fop = FAB$M_NAM;
        !          3409: 
        !          3410:   from_nam.nam$l_esa = from_esn;
        !          3411:   from_nam.nam$b_ess = sizeof from_esn;
        !          3412: 
        !          3413:   to_fab.fab$l_fna = to;
        !          3414:   to_fab.fab$b_fns = strlen (to);
        !          3415:   to_fab.fab$l_nam = &to_nam;
        !          3416:   to_fab.fab$l_fop = FAB$M_NAM;
        !          3417: 
        !          3418:   to_nam.nam$l_esa = to_esn;
        !          3419:   to_nam.nam$b_ess = sizeof to_esn;
        !          3420: 
        !          3421:   status = SYS$RENAME (&from_fab, 0, 0, &to_fab);
        !          3422: 
        !          3423:   if (status & 1)
        !          3424:     return 0;
        !          3425:   else
        !          3426:     {
        !          3427:       if (status == RMS$_DEV)
        !          3428:        errno = EXDEV;
        !          3429:       else
        !          3430:        errno = EVMSERR;
        !          3431:       vaxc$errno = status;
        !          3432:       return -1;
        !          3433:     }
        !          3434: }
        !          3435: 
        !          3436: link (file, new)
        !          3437:      char * file, * new;
        !          3438: {
        !          3439:   register status;
        !          3440:   struct FAB fab;
        !          3441:   struct NAM nam;
        !          3442:   unsigned short fid[3];
        !          3443:   char esa[NAM$C_MAXRSS];
        !          3444: 
        !          3445:   fab = cc$rms_fab;
        !          3446:   fab.fab$l_fop = FAB$M_OFP;
        !          3447:   fab.fab$l_fna = file;
        !          3448:   fab.fab$b_fns = strlen (file);
        !          3449:   fab.fab$l_nam = &nam;
        !          3450: 
        !          3451:   nam = cc$rms_nam;
        !          3452:   nam.nam$l_esa = esa;
        !          3453:   nam.nam$b_ess = NAM$C_MAXRSS;
        !          3454: 
        !          3455:   status = SYS$PARSE (&fab);
        !          3456:   if ((status & 1) == 0)
        !          3457:     {
        !          3458:       errno = EVMSERR;
        !          3459:       vaxc$errno = status;
        !          3460:       return -1;
        !          3461:     }
        !          3462:   status = SYS$SEARCH (&fab);
        !          3463:   if ((status & 1) == 0)
        !          3464:     {
        !          3465:       errno = EVMSERR;
        !          3466:       vaxc$errno = status;
        !          3467:       return -1;
        !          3468:     }
        !          3469: 
        !          3470:   fid[0] = nam.nam$w_fid[0];
        !          3471:   fid[1] = nam.nam$w_fid[1];
        !          3472:   fid[2] = nam.nam$w_fid[2];
        !          3473: 
        !          3474:   fab.fab$l_fna = new;
        !          3475:   fab.fab$b_fns = strlen (new);
        !          3476: 
        !          3477:   status = SYS$PARSE (&fab);
        !          3478:   if ((status & 1) == 0)
        !          3479:     {
        !          3480:       errno = EVMSERR;
        !          3481:       vaxc$errno = status;
        !          3482:       return -1;
        !          3483:     }
        !          3484: 
        !          3485:   nam.nam$w_fid[0] = fid[0];
        !          3486:   nam.nam$w_fid[1] = fid[1];
        !          3487:   nam.nam$w_fid[2] = fid[2];
        !          3488: 
        !          3489:   nam.nam$l_esa = nam.nam$l_name;
        !          3490:   nam.nam$b_esl = nam.nam$b_name + nam.nam$b_type + nam.nam$b_ver;
        !          3491: 
        !          3492:   status = SYS$ENTER (&fab);
        !          3493:   if ((status & 1) == 0)
        !          3494:     {
        !          3495:       errno = EVMSERR;
        !          3496:       vaxc$errno = status;
        !          3497:       return -1;
        !          3498:     }
        !          3499: 
        !          3500:   return 0;
        !          3501: }
        !          3502: 
        !          3503: croak (badfunc)
        !          3504:      char *badfunc;
        !          3505: {
        !          3506:   printf ("%s not yet implemented\r\n", badfunc);
        !          3507:   reset_sys_modes ();
        !          3508:   exit (1);
        !          3509: }
        !          3510: 
        !          3511: long
        !          3512: random ()
        !          3513: {
        !          3514:   /* Arrange to return a range centered on zero.  */
        !          3515:   return rand () - (1 << 30);
        !          3516: }
        !          3517: 
        !          3518: srandom (seed)
        !          3519: {
        !          3520:   srand (seed);
        !          3521: }
        !          3522: #endif /* VMS */
        !          3523: 
        !          3524: #ifdef AIX
        !          3525: 
        !          3526: /* Get files for keyboard remapping */
        !          3527: #define HFNKEYS 2
        !          3528: #include <sys/hft.h>
        !          3529: #include <sys/devinfo.h>
        !          3530: 
        !          3531: /* Called from init_sys_modes.  */
        !          3532: hft_init ()
        !          3533: {
        !          3534:   /* On AIX the default hft keyboard mapping uses backspace rather than delete
        !          3535:      as the rubout key's ASCII code.  Here this is changed.  The bug is that
        !          3536:      there's no way to determine the old mapping, so in reset_sys_modes
        !          3537:      we need to assume that the normal map had been present.  Of course, this
        !          3538:      code also doesn't help if on a terminal emulator which doesn't understand
        !          3539:      HFT VTD's. */
        !          3540:   {
        !          3541:     struct hfbuf buf;
        !          3542:     struct hfkeymap keymap;
        !          3543: 
        !          3544:     buf.hf_bufp = (char *)&keymap;
        !          3545:     buf.hf_buflen = sizeof (keymap);
        !          3546:     keymap.hf_nkeys = 2;
        !          3547:     keymap.hfkey[0].hf_kpos = 15;
        !          3548:     keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
        !          3549:     keymap.hfkey[0].hf_page = '<';
        !          3550:     keymap.hfkey[0].hf_char = 127;
        !          3551:     keymap.hfkey[1].hf_kpos = 15;
        !          3552:     keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
        !          3553:     keymap.hfkey[1].hf_page = '<';
        !          3554:     keymap.hfkey[1].hf_char = 127;
        !          3555:     hftctl (0, HFSKBD, &buf);
        !          3556:   }
        !          3557:   /* The HFT system on AIX doesn't optimize for scrolling, so it's really ugly
        !          3558:      at times.  Here we determine if we are on an HFT by trying to get an
        !          3559:      HFT error code.  If this call works, we must be on an HFT. */
        !          3560:   if (ioctl (0, HFQEIO, 0) != -1)
        !          3561:     line_ins_del_ok = char_ins_del_ok = 0;
        !          3562: }
        !          3563: 
        !          3564: /* Reset the rubout key to backspace. */
        !          3565: 
        !          3566: hft_reset ()
        !          3567: {
        !          3568:   struct hfbuf buf;
        !          3569:   struct hfkeymap keymap;
        !          3570: 
        !          3571:   buf.hf_bufp = (char *)&keymap;
        !          3572:   buf.hf_buflen = sizeof(keymap);
        !          3573:   keymap.hf_nkeys = 2;
        !          3574:   keymap.hfkey[0].hf_kpos = 15;
        !          3575:   keymap.hfkey[0].hf_kstate = HFMAPCHAR | HFSHFNONE;
        !          3576:   keymap.hfkey[0].hf_page = '<';
        !          3577:   keymap.hfkey[0].hf_char = 8;
        !          3578:   keymap.hfkey[1].hf_kpos = 15;
        !          3579:   keymap.hfkey[1].hf_kstate = HFMAPCHAR | HFSHFSHFT;
        !          3580:   keymap.hfkey[1].hf_page = '<';
        !          3581:   keymap.hfkey[1].hf_char = 8;
        !          3582:   hftctl (0, HFSKBD, &buf);
        !          3583: }
        !          3584: 
        !          3585: #endif /* AIX */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.