Annotation of GNUtools/emacs/src/sysdep.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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