Annotation of 43BSD/contrib/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 Richard M. Stallman.
                      3: 
                      4: This file is part of GNU Emacs.
                      5: 
                      6: GNU Emacs is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU Emacs General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU Emacs, but only under the conditions described in the
                     15: GNU Emacs General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU Emacs so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: #include <signal.h>
                     23: 
                     24: #include "config.h"
                     25: #include "lisp.h"
                     26: #undef NULL
                     27: 
                     28: /* In this file, open, read and write refer to the system calls,
                     29:    not our sugared interfaces  sys_open, sys_read and sys_write.
                     30:    Contrariwise, for systems where we use the system calls directly,
                     31:    define sys_read, etc. here as aliases for them.  */
                     32: #ifndef read
                     33: #define sys_read read
                     34: #define sys_write write
                     35: #endif /* `read' is not a macro */
                     36: 
                     37: #undef read
                     38: #undef write
                     39: 
                     40: #ifndef open
                     41: #define sys_open open
                     42: #endif /* `open' is not a macro.  */
                     43: 
                     44: #undef open
                     45: 
                     46: #include <stdio.h>
                     47: #include <sys/types.h>
                     48: #include <sys/stat.h>
                     49: 
                     50: #if defined (USG) || (defined (BSD) && !defined (BSD4_1))
                     51: #include <fcntl.h>
                     52: #endif
                     53: 
                     54: #ifdef BSD
                     55: #include <sys/ioctl.h>
                     56: #ifdef BSD4_1
                     57: #include <wait.h>
                     58: #else /* not 4.1 */
                     59: #include <sys/wait.h>
                     60: #endif /* not 4.1 */
                     61: #include <sgtty.h>
                     62: #define TERMINAL struct sgttyb
                     63: #define OSPEED(str) str.sg_ospeed
                     64: #define TABS_OK(str) ((str.sg_flags & XTABS) != XTABS)
                     65: #endif
                     66: 
                     67: /* Get rid of LLITOUT in 4.1, since it is said to stimulate kernel bugs.  */
                     68: #ifdef BSD4_1
                     69: #undef LLITOUT
                     70: #define LLITOUT 0
                     71: #endif /* 4.1 */
                     72: 
                     73: #ifdef USG
                     74: #include <termio.h>
                     75: #include <sys/utsname.h>
                     76: #include <memory.h>
                     77: #include <string.h>
                     78: #ifdef HAVE_TIMEVAL
                     79: #ifdef HPUX
                     80: #include <time.h>
                     81: #else
                     82: #include <sys/time.h>
                     83: #endif
                     84: #endif /* HAVE_TIMEVAL */
                     85: #include <errno.h>
                     86: #define TIOCGETP TCGETA
                     87: #define TIOCSETN TCSETA
                     88: #define TIOCSETP TCSETAF
                     89: #define TERMINAL struct termio
                     90: #define OSPEED(str) (str.c_cflag & CBAUD)
                     91: #define TABS_OK(str) ((str.c_oflag & TABDLY) != TAB3)
                     92: #endif /* USG */
                     93: 
                     94: #include "termhooks.h"
                     95: #include "termchar.h"
                     96: #include "termopts.h"
                     97: #include "dispextern.h"
                     98: 
                     99: #ifdef NONSYSTEM_DIR_LIBRARY
                    100: #include "ndir.h"
                    101: #endif /* NONSYSTEM_DIR_LIBRARY */
                    102: 
                    103: /* Define SIGCHLD as an alias for SIGCLD.  There are many conditionals
                    104:    testing SIGCHLD.  */
                    105: 
                    106: #if !defined (SIGCHLD) && defined (SIGCLD)
                    107: #define SIGCHLD SIGCLD
                    108: #endif /* SIGCLD and not SIGCHLD */
                    109: 
                    110: static int baud_convert[] =
                    111:   {
                    112:     0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
                    113:     1800, 2400, 4800, 9600, 19200, 38400
                    114:   };
                    115: 
                    116: extern short ospeed;
                    117: 
                    118: discard_tty_input ()
                    119: {
                    120:   TERMINAL buf;
                    121: 
                    122:   if (noninteractive)
                    123:     return;
                    124: 
                    125:   ioctl (0, TIOCGETP, &buf);
                    126:   ioctl (0, TIOCSETP, &buf);
                    127: }
                    128: 
                    129: #ifdef SIGTSTP
                    130: 
                    131: stuff_char (c)
                    132:      char c;
                    133: {
                    134: /* Should perhaps error if in batch mode */
                    135: #ifdef TIOCSTI
                    136:   ioctl (0, TIOCSTI, &c);
                    137: #else /* no TIOCSTI */
                    138:   error ("Cannot stuff terminal input characters in this version of Unix.");
                    139: #endif /* no TIOCSTI */
                    140: }
                    141: 
                    142: #endif /* SIGTSTP */
                    143: 
                    144: init_baud_rate ()
                    145: {
                    146:   TERMINAL sg;
                    147: 
                    148:   if (noninteractive)
                    149:     ospeed = 0;
                    150:   else
                    151:     {
                    152:       ioctl (0, TIOCGETP, &sg);
                    153:       ospeed = OSPEED (sg);
                    154:     }
                    155:   baud_rate = ospeed == 0 ? 1200
                    156:     : ospeed < sizeof baud_convert / sizeof baud_convert[0]
                    157:       ? baud_convert[ospeed] : 9600;
                    158: }
                    159: 
                    160: set_exclusive_use (fd)
                    161:      int fd;
                    162: {
                    163: #ifdef FIOCLEX
                    164:   ioctl (fd, FIOCLEX, 0);
                    165: #endif
                    166:   /* Ok to do nothing if this feature does not exist */
                    167: }
                    168: 
                    169: #ifndef subprocesses
                    170: 
                    171: wait_without_blocking ()
                    172: {
                    173: #ifndef USG
                    174:   wait3 (0, WNOHANG | WUNTRACED, 0);
                    175: #else
                    176:   croak ("wait_without_blocking");
                    177: #endif
                    178: }
                    179: 
                    180: #endif /* not subprocesses */
                    181: 
                    182: int wait_debugging;   /* Set nonzero to make following function work under dbx
                    183:                         (at least for bsd).  */
                    184: 
                    185: /* Wait for subprocess with process id `pid' to terminate and
                    186:    make sure it will get eliminated (not remain forever as a zombie) */
                    187: 
                    188: wait_for_termination (pid)
                    189:      int pid;
                    190: {
                    191:   int status;
                    192:   while (1)
                    193:     {
                    194: #ifdef subprocesses
                    195: #ifdef BSD
                    196:       /* Note that kill returns -1 even if the process is just a zombie now.
                    197:         But inevitably a SIGCHLD interrupt should be generated
                    198:         and child_sig will do wait3 and make the process go away. */
                    199:       /* There is some indication that there is a bug involved with
                    200:         termination of subprocesses, perhaps involving a kernel bug too,
                    201:         but no idea what it is.  Just as a hunch we signal SIGCHLD to see
                    202:         if that causes the problem to go away or get worse.  */
                    203: #ifdef BSD4_1
                    204:       extern int synch_process_pid;
                    205:       sighold (SIGCHLD);
                    206:       if (synch_process_pid == 0)
                    207:        {
                    208:           sigrelse (SIGCHLD);
                    209:          break;
                    210:        }
                    211:       if (wait_debugging)
                    212:        sleep (1);
                    213:       else
                    214:        sigpause (SIGCHLD);
                    215: #else /* not BSD4_1 */
                    216:       sigsetmask (1 << (SIGCHLD - 1));
                    217:       if (0 > kill (pid, 0))
                    218:         {
                    219:          sigsetmask (0);
                    220:          kill (getpid (), SIGCHLD);
                    221:          break;
                    222:        }
                    223:       if (wait_debugging)
                    224:        sleep (1);
                    225:       else
                    226:        sigpause (0);
                    227: #endif /* not BSD4_1 */
                    228: #else /* not BSD */
                    229: #ifdef UNIPLUS
                    230:       if (0 > kill (pid, 0))
                    231:        break;
                    232:       wait (0);
                    233: #else /* neither BSD nor UNIPLUS: random sysV */
                    234:       if (0 > kill (pid, 0))
                    235:        break;
                    236:       pause ();
                    237: #endif /* not UNIPLUS */
                    238: #endif /* not BSD */
                    239: #else /* not subprocesses */
                    240: #ifndef BSD4_1
                    241:       if (0 > kill (pid, 0))
                    242:        break;
                    243:       wait (0);
                    244: #else /* BSD4_1 */
                    245:       int status;
                    246:       status = wait (0);
                    247:       if (status == pid || status == -1)
                    248:        break;
                    249: #endif /* BSD4_1 */
                    250: #endif /* not subprocesses */
                    251:     }
                    252: }
                    253:  
                    254: /*
                    255:  *     Insert description of what this command is really supposed to
                    256:  *     to (I.E. what state is the child process line to be placed into,
                    257:  *     and why).  I have tried to interpret this as much as possible from
                    258:  *     the BSD setup and map to an appropriate USG control, but don't
                    259:  *     guarantee the results.  fnf@unisoft
                    260:  */
                    261: 
                    262: child_setup_tty (out)
                    263:      int out;
                    264: {
                    265:   TERMINAL s;
                    266: 
                    267:   ioctl (out, TIOCGETP, &s);
                    268: #ifdef USG
                    269:   s.c_oflag |= OPOST;          /* Enable output postprocessing */
                    270:   s.c_oflag &= ~ONLCR;         /* Disable map of NL to CR-NL on output */
                    271:   s.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);        /* No output delays */
                    272:   s.c_lflag &= ~ECHO;          /* Disable echo */
                    273:   s.c_lflag &= ~ICANON;                /* Disable erase/kill processing */
                    274:   s.c_lflag |= ISIG;           /* Enable signals */
                    275:   s.c_iflag &= ~IUCLC;         /* Disable map of upper case to lower on input */
                    276:   s.c_oflag &= ~OLCUC;         /* Disable map of lower case to upper on output */
                    277:   s.c_cc[VMIN] = 1;            /* minimum number of characters to accept */
                    278:   s.c_cc[VTIME] = 0;           /* wait forever for at least 1 character */
                    279: #else /* not USG */
                    280:   s.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE | CBREAK | TANDEM);
                    281: #endif /* not USG */
                    282:   ioctl (out, TIOCSETN, &s);
                    283: 
                    284: #ifdef BSD4_1
                    285:   if (interrupt_input)
                    286:     reset_sigio ();
                    287: #endif /* BSD4_1 */
                    288: }
                    289: 
                    290: setpgrp_of_tty (pid)
                    291:      int pid;
                    292: {
                    293: #ifdef TIOCSPGRP
                    294:   ioctl (0, TIOCSPGRP, &pid);
                    295: #else
                    296:   /* Just ignore this for now and hope for the best */
                    297: #endif
                    298: }
                    299: 
                    300: #ifdef F_SETFL
                    301: 
                    302: init_sigio ()
                    303: {
                    304:   request_sigio ();
                    305: }
                    306: 
                    307: reset_sigio ()
                    308: {
                    309:   unrequest_sigio ();
                    310: }
                    311: 
                    312: #ifdef FASYNC          /* F_SETFL does not imply existance of FASYNC */
                    313: int old_fcntl_flags;
                    314: 
                    315: request_sigio ()
                    316: {
                    317:   old_fcntl_flags = fcntl (0, F_GETFL, 0);
                    318:   fcntl (0, F_SETFL, old_fcntl_flags | FASYNC);
                    319: }
                    320: 
                    321: unrequest_sigio ()
                    322: {
                    323:   fcntl (0, F_SETFL, old_fcntl_flags);
                    324: }
                    325: 
                    326: #else /* no FASYNC */
                    327:  
                    328: request_sigio ()
                    329: {
                    330:   croak ("request_sigio");
                    331: }
                    332:  
                    333: unrequest_sigio ()
                    334: {
                    335:   croak ("unrequest_sigio");
                    336: }
                    337:  
                    338: #endif /* FASYNC */
                    339: #endif /* F_SETFL */
                    340: 
                    341: TERMINAL old_gtty;             /* The initial tty mode bits */
                    342: 
                    343: int term_initted;              /* 1 if outer tty status has been recorded */
                    344: 
                    345: #ifdef F_SETOWN
                    346: int old_fcntl_owner;
                    347: #endif /* F_SETOWN */
                    348: 
                    349: #ifdef TIOCGLTC
                    350: struct tchars old_tchars;
                    351: struct ltchars old_ltchars;
                    352: int old_lmode;
                    353: 
                    354: int lmode;                     /* Current lmode value. */
                    355:                                /* Needed as global for 4.1 */
                    356: #endif /* TIOCGLTC */
                    357: 
                    358: /* This may also be defined in stdio,
                    359:    but if so, this does no harm,
                    360:    and using the same name avoids wasting the other one's space.  */
                    361: 
                    362: #ifdef USG
                    363: unsigned char _sobuf[BUFSIZ+8];
                    364: #else
                    365: char _sobuf[BUFSIZ];
                    366: #endif
                    367:  
                    368: init_sys_modes ()
                    369: {
                    370:   TERMINAL sg;
                    371: #ifdef TIOCGLTC
                    372:   struct tchars tchars;
                    373:   static struct tchars new_tchars = {-1,-1,-1,-1,-1,-1};
                    374:   static struct ltchars new_ltchars = {-1,-1,-1,-1,-1,-1};
                    375: #endif
                    376: 
                    377:   if (noninteractive)
                    378:     return;
                    379: 
                    380:   ioctl (0, TIOCGETP, &old_gtty);
                    381:   if (!read_socket_hook)
                    382:     {
                    383:       sg = old_gtty;
                    384: 
                    385: #ifdef USG
                    386:       sg.c_iflag |= (IGNBRK);  /* Ignore break condition */
                    387:       sg.c_iflag &= ~ICRNL;    /* Disable map of CR to NL on input */
                    388: #ifdef ISTRIP
                    389:       sg.c_iflag &= ~ISTRIP;   /* don't strip 8th bit on input */
                    390: #endif
                    391:       sg.c_lflag &= ~ECHO;     /* Disable echo */
                    392:       sg.c_lflag &= ~ICANON;   /* Disable erase/kill processing */
                    393:       sg.c_lflag |= ISIG;      /* Enable signals */
                    394:       if (flow_control)
                    395:        {
                    396:          sg.c_iflag |= IXON;   /* Enable start/stop output control */
                    397: #ifdef IXANY
                    398:          sg.c_iflag &= ~IXANY;
                    399: #endif /* IXANY */
                    400:        }
                    401:       else
                    402:        sg.c_iflag &= ~IXON;    /* Disable start/stop output control */
                    403:       sg.c_oflag &= ~ONLCR;    /* Disable map of NL to CR-NL on output */
                    404:       sg.c_oflag &= ~TAB3;     /* Disable tab expansion */
                    405: #ifdef CS8
                    406:       sg.c_cflag |= CS8;       /* allow 8th bit on input */
                    407:       sg.c_cflag &= ~PARENB;   /* Don't check parity */
                    408: #endif
                    409:       sg.c_cc[VINTR] = '\007'; /* ^G gives SIGINT */
                    410: #ifdef HPUX
                    411:       /* Can't use CDEL as that makes Meta-DEL do SIGQUIT.
                    412:         Instead set up C-g for both; we handle both alike
                    413:         so which one it really gives us does not matter.  */
                    414:       sg.c_cc[VQUIT] = '\007';
                    415: #else /* not HPUX */
                    416:       sg.c_cc[VQUIT] = CDEL;   /* Turn off SIGQUIT */
                    417: #endif /* not HPUX */
                    418:       sg.c_cc[VMIN] = 1;       /* Input should wait for at least 1 char */
                    419:       sg.c_cc[VTIME] = 0;      /* no matter how long that takes.  */
                    420: #ifdef VSWTCH
                    421:       sg.c_cc[VSWTCH] = CDEL;  /* Turn off shell layering use of C-z */
                    422: #endif /* VSWTCH */
                    423: #else /* if not USG */
                    424:       sg.sg_flags &= ~(ECHO | CRMOD | XTABS);
                    425:       sg.sg_flags |= ANYP;
                    426:       sg.sg_flags |= interrupt_input ? RAW : CBREAK;
                    427: #endif /* not USG (BSD, that is) */
                    428: 
                    429:       ioctl (0, TIOCSETN, &sg);
                    430: 
                    431: #ifdef F_SETFL
                    432: #ifdef F_GETOWN                /* F_SETFL does not imply existance of F_GETOWN */
                    433:       if (interrupt_input)
                    434:        {
                    435:          old_fcntl_owner = fcntl (0, F_GETOWN, 0);
                    436:          fcntl (0, F_SETOWN, getpid ());
                    437:          init_sigio ();
                    438:        }
                    439: #endif /* F_GETOWN */
                    440: #endif /* F_SETFL */
                    441: 
                    442:       /* If going to use CBREAK mode, we must request C-g to interrupt
                    443:           and turn off start and stop chars, etc.
                    444:           If not going to use CBREAK mode, do this anyway
                    445:           so as to turn off local flow control for user coming over
                    446:           network on 4.2; in this case, only t_stopc and t_startc really matter.  */
                    447: #ifdef TIOCGLTC
                    448:       ioctl (0, TIOCGETC, &old_tchars);
                    449:       ioctl (0, TIOCGLTC, &old_ltchars);
                    450:       ioctl (0, TIOCLGET, &old_lmode);
                    451: 
                    452:       /* Note: if not using CBREAK mode, it makes no difference how we set this */
                    453:       tchars = new_tchars;
                    454:       tchars.t_intrc = 07;
                    455:       if (flow_control)
                    456:        {
                    457:          tchars.t_startc = '\021';
                    458:          tchars.t_stopc = '\023';
                    459:        }
                    460: /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
                    461: #ifndef LPASS8
                    462: #define LPASS8 0
                    463: #endif
                    464: 
                    465: #ifdef BSD4_1
                    466: #define LNOFLSH 0100000
                    467: #endif
                    468: 
                    469:       lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_lmode;
                    470: 
                    471:       ioctl (0, TIOCSETC, &tchars);
                    472:       ioctl (0, TIOCSLTC, &new_ltchars);
                    473:       ioctl (0, TIOCLSET, &lmode);
                    474: #endif TIOCGLTC
                    475: #ifdef BSD4_1
                    476:       if (interrupt_input)
                    477:        init_sigio ();
                    478: #endif
                    479:     }
                    480:   screen_garbaged = 1;
                    481:   setbuf (stdout, _sobuf);
                    482:   term_initted = 1;
                    483:   set_terminal_modes ();
                    484: }
                    485: 
                    486: /* Return nonzero if safe to use tabs in output.
                    487:    At the time this is called, init_sys_modes has not been done yet.  */
                    488:    
                    489: tabs_safe_p ()
                    490: {
                    491:   TERMINAL sg;
                    492:   if (noninteractive)
                    493:     return 1;
                    494:   ioctl (0, TIOCGETP, &sg);
                    495:   return (TABS_OK(sg));
                    496: }
                    497: 
                    498: /* Get terminal size from system.
                    499:    Store number of lines into *heightp and width into *widthp.
                    500:    If zero or a negative number is stored, the value is not valid.  */
                    501: 
                    502: get_screen_size (widthp, heightp)
                    503:      int *widthp, *heightp;
                    504: {
                    505: /* Define the 4.3 names in terms of the Sun names
                    506:    if the latter exist and the former do not.  */
                    507: #if !defined (TIOCGWINSZ) && defined (TIOCGSIZE)
                    508: #define TIOCGWINSZ TIOCGSIZE
                    509: #define winsize ttysize
                    510: #define ws_row ts_lines
                    511: #define ws_col ts_cols
                    512: #endif /* Sun */
                    513: 
                    514: #ifdef TIOCGWINSZ
                    515:   struct winsize size;
                    516:   *widthp = 0;
                    517:   *heightp = 0;
                    518:   if (ioctl (0, TIOCGWINSZ, &size) < 0)
                    519:     return;
                    520:   *widthp = size.ws_col;
                    521:   *heightp = size.ws_row;
                    522: #else /* system doesn't know size */
                    523:   *widthp = 0;
                    524:   *heightp = 0;
                    525: #endif /* system does not know size */
                    526: }
                    527: 
                    528: reset_sys_modes ()
                    529: {
                    530:   if (noninteractive)
                    531:     {
                    532:       fflush (stdout);
                    533:       return;
                    534:     }
                    535:   if (!term_initted)
                    536:     return;
                    537:   topos (screen_height - 1, 0);
                    538:   clear_end_of_line (screen_width);
                    539:   /* clear_end_of_line may move the cursor */
                    540:   topos (screen_height - 1, 0);
                    541:   reset_terminal_modes ();
                    542:   fflush (stdout);
                    543:   if (read_socket_hook)
                    544:     return;
                    545: #ifdef TIOCGLTC
                    546:   ioctl (0, TIOCSETC, &old_tchars);
                    547:   ioctl (0, TIOCSLTC, &old_ltchars);
                    548:   ioctl (0, TIOCLSET, &old_lmode);
                    549: #endif /* TIOCGLTC */
                    550: #ifdef F_SETFL
                    551: #ifdef F_SETOWN                /* F_SETFL does not imply existance of F_SETOWN */
                    552:   if (interrupt_input)
                    553:     {
                    554: #ifdef FASYNC
                    555:       old_fcntl_flags &= ~FASYNC;
                    556: #endif /* FASYNC */
                    557:       reset_sigio ();
                    558:       reset_sigio ();
                    559:       fcntl (0, F_SETOWN, old_fcntl_owner);
                    560:     }
                    561: #endif /* F_SETOWN */
                    562: #endif /* F_SETFL */
                    563: #ifdef BSD4_1
                    564:   if (interrupt_input)
                    565:     reset_sigio ();
                    566: #endif /* BSD4_1 */
                    567:   ioctl (0, TIOCSETN, &old_gtty);
                    568: }
                    569: 
                    570: /*
                    571:  *     flush any pending output
                    572:  */
                    573:  
                    574: flush_pending_output (channel)
                    575:      int channel;
                    576: {
                    577: #ifdef USG
                    578:   ioctl (channel, TCFLSH, 1);
                    579: #else
                    580:   ioctl (channel, TIOCFLUSH, 0);
                    581: #endif
                    582: }
                    583:  
                    584: /*
                    585:  *     Return the address of the start of the text segment prior to
                    586:  *     doing an unexec().  After unexec() the return value is undefined.
                    587:  *     See crt0.c for further explanation and _start().
                    588:  *
                    589:  */
                    590: 
                    591: char *
                    592: start_of_text ()
                    593: {
                    594: #ifdef TEXT_START
                    595:   return ((char *) TEXT_START);
                    596: #else
                    597:   extern int _start ();
                    598:   return ((char *) _start);
                    599: #endif
                    600: }
                    601: 
                    602: /*
                    603:  *     Return the address of the start of the data segment prior to
                    604:  *     doing an unexec().  After unexec() the return value is undefined.
                    605:  *     See crt0.c for further information and definition of data_start.
                    606:  *
                    607:  *     Apparently, on BSD systems this is etext at startup.  On
                    608:  *     USG systems (swapping) this is highly mmu dependent and
                    609:  *     is also dependent on whether or not the program is running
                    610:  *     with shared text.  Generally there is a (possibly large)
                    611:  *     gap between end of text and start of data with shared text.
                    612:  *
                    613:  *     On Uniplus+ systems with shared text, data starts at a
                    614:  *     fixed address.  Each port (from a given oem) is generally
                    615:  *     different, and the specific value of the start of data can
                    616:  *     be obtained via the UniPlus+ specific "uvar(2)" system call,
                    617:  *     however the method outlined in crt0.c seems to be more portable.
                    618:  *
                    619:  *     Probably what will have to happen when a USG unexec is available,
                    620:  *     at least on UniPlus, is temacs will have to be made unshared so
                    621:  *     that text and data are contiguous.  Then once loadup is complete,
                    622:  *     unexec will produce a shared executable where the data can be
                    623:  *     at the normal shared text boundry and the startofdata variable
                    624:  *     will be patched by unexec to the correct value.
                    625:  *
                    626:  */
                    627:  
                    628: char *
                    629: start_of_data ()
                    630: {
                    631: #ifdef DATA_START
                    632:   return ((char *) DATA_START);
                    633: #else
                    634:   extern int data_start;
                    635:   return ((char *) &data_start);
                    636: #endif
                    637: }
                    638: 
                    639: #ifdef NOTDEF
                    640: 
                    641: /*
                    642:  *     Return the address of the end of the text segment prior to
                    643:  *     doing an unexec().  After unexec() the return value is undefined.
                    644:  */
                    645:  
                    646: char *
                    647: end_of_text ()
                    648: {
                    649: #ifdef TEXT_END
                    650:   return ((char *) TEXT_END);
                    651: #else
                    652:   extern int etext;
                    653:   return ((char *) &etext);
                    654: #endif
                    655: }
                    656:  
                    657: /*
                    658:  *     Return the address of the end of the data segment prior to
                    659:  *     doing an unexec().  After unexec() the return value is undefined.
                    660:  */
                    661: 
                    662: char *
                    663: end_of_data ()
                    664: {
                    665: #ifdef DATA_END
                    666:   return ((char *) DATA_END);
                    667: #else
                    668:   extern int edata;
                    669:   return ((char *) &edata);
                    670: #endif
                    671: }
                    672: 
                    673: #endif NOTDEF
                    674: 
                    675: 
                    676: /* Get_system_name returns as its value
                    677:  a string for the Lisp function system-name to return. */
                    678: 
                    679: #ifdef USG
                    680: struct utsname get_system_name_name;
                    681: #endif
                    682: #ifdef BSD4_1
                    683: #include <whoami.h>
                    684: #endif
                    685: 
                    686: char *
                    687: get_system_name ()
                    688: {
                    689: #ifdef USG
                    690:   uname (&get_system_name_name);
                    691:   return (get_system_name_name.nodename);
                    692: #else /* Not USG */
                    693: #ifdef BSD4_1
                    694:   return sysname;
                    695: #else /* BSD, not 4.1 */
                    696:   static char system_name_saved[32];
                    697:   (void) gethostname (system_name_saved, sizeof (system_name_saved));
                    698:   return (system_name_saved);
                    699: #endif /* BSD, not 4.1 */
                    700: #endif /* not USG */
                    701: }
                    702: 
                    703: #ifndef HAVE_SELECT
                    704: 
                    705: /* Emulate as much as select as is possible under 4.1 and needed by Gnu Emacs
                    706:  * Only checks read descriptors.
                    707:  */
                    708: /* How long to wait between checking fds in select */
                    709: #define SELECT_PAUSE 1
                    710: int select_alarmed;
                    711: 
                    712: select_alarm ()
                    713: {
                    714:   select_alarmed = 1;
                    715: #ifdef BSD4_1
                    716:   sigrelse (SIGALRM);
                    717: #else /* not BSD4_1 */
                    718:   signal (SIGALRM, SIG_IGN);
                    719: #endif /* not BSD4_1 */
                    720: }
                    721: 
                    722: /* Only rfds are checked and timeout must point somewhere */
                    723: int
                    724: select (nfds, rfds, wfds, efds, timeout)
                    725:      int nfds;
                    726:      int *rfds, *wfds, *efds, *timeout;
                    727: {
                    728:   int ravail = 0, orfds = 0, old_alarm, val;
                    729:   extern int kbd_count;
                    730:   extern int proc_buffered_char[];
                    731:   extern int child_changed;
                    732:   int (*old_trap) ();
                    733:   char buf;
                    734: 
                    735:   if (rfds)
                    736:     {
                    737:       orfds = *rfds;
                    738:       *rfds = 0;
                    739:     }
                    740:   if (wfds)
                    741:     *wfds = 0;
                    742:   if (efds)
                    743:     *efds = 0;
                    744: 
                    745:   /* If we are looking only for the terminal, with no timeout,
                    746:      just read it and wait -- that's more efficient.  */
                    747:   if (orfds == 1 && *timeout == 100000 && !child_changed)
                    748:     {
                    749:       if (!kbd_count)
                    750:        read_input_waiting ();
                    751:       *rfds = 1;
                    752:       return 1;
                    753:     }
                    754: 
                    755:   /* Once a second, till the timer expires, check all the flagged read
                    756:    * descriptors to see if any input is available.  If there is some then
                    757:    * set the corresponding bit in the return copy of rfds.
                    758:    */ 
                    759:   while (1)
                    760:     {
                    761:       register int to_check, bit, fd;
                    762: 
                    763:       if (rfds)
                    764:        {
                    765:          for (to_check = nfds, bit = 1, fd = 0; --to_check >= 0; bit <<= 1, fd++)
                    766:            {
                    767:              if (orfds & bit)
                    768:                {
                    769:                  int avail = 0, status = 0;
                    770: 
                    771:                  if (bit == 1)
                    772:                    avail = detect_input_pending(); /* Special keyboard handler */
                    773:                  else
                    774:                    {
                    775: #ifdef FIONREAD
                    776:                      status = ioctl (fd, FIONREAD, &avail);
                    777: #else /* no FIONREAD */
                    778:                      /* Hoping it will return -1 if nothing available
                    779:                         or 0 if all 0 chars requested are read.  */
                    780:                      if (proc_buffered_char[fd] >= 0)
                    781:                        avail = 1;
                    782:                      else
                    783:                        {
                    784:                          avail = read (fd, &buf, 1);
                    785:                          if (avail > 0)
                    786:                            proc_buffered_char[fd] = buf;
                    787:                        }
                    788: #endif /* no FIONREAD */
                    789:                    }
                    790:                  if (status >= 0 && avail > 0)
                    791:                    {
                    792:                      (*rfds) |= bit;
                    793:                      ravail++;
                    794:                    }
                    795:                }
                    796:            }
                    797:        }
                    798:       if (*timeout == 0 || ravail != 0 || child_changed)
                    799:        break;
                    800:       old_alarm = alarm (0);
                    801:       old_trap = signal (SIGALRM, select_alarm);
                    802:       select_alarmed = 0;
                    803:       alarm (SELECT_PAUSE);
                    804:       /* Wait for a SIGALRM (or maybe a SIGTINT) */
                    805:       while (select_alarmed == 0 && *timeout != 0 && child_changed == 0)
                    806:        {
                    807:          /* If we are interested in terminal input,
                    808:             wait by reading the terminal.
                    809:             That makes instant wakeup for terminal input at least.  */
                    810:          if (orfds & 1)
                    811:            {
                    812:              read_input_waiting ();
                    813:              if (kbd_count)
                    814:                select_alarmed = 1;
                    815:            }
                    816:          else
                    817:            pause();
                    818:        }
                    819:       (*timeout) -= SELECT_PAUSE;
                    820:       /* Reset the old alarm if there was one */
                    821:       alarm (0);
                    822:       signal (SIGALRM, old_trap);
                    823:       if (old_alarm != 0)
                    824:        {
                    825:          /* Reset or forge an interrupt for the original handler. */
                    826:          old_alarm -= SELECT_PAUSE;
                    827:          if (old_alarm <= 0)
                    828:            kill (getpid (), SIGALRM); /* Fake an alarm with the orig' handler */
                    829:          else
                    830:            alarm (old_alarm);
                    831:        }
                    832:       if (*timeout == 0)  /* Stop on timer being cleared */
                    833:        break;
                    834:     }
                    835:   return ravail;
                    836: }
                    837: 
                    838: /* Read keyboard input into the standard buffer,
                    839:    waiting for at least one character.  */
                    840: 
                    841: read_input_waiting ()
                    842: {
                    843:   extern int kbd_count;
                    844:   extern unsigned char kbd_buffer[];
                    845:   extern unsigned char *kbd_ptr;
                    846:   int val = read (fileno(stdin), kbd_buffer, 1);
                    847:   if (val > 0)
                    848:     {
                    849:       kbd_ptr = kbd_buffer;
                    850:       kbd_count = val;
                    851:     }
                    852: }
                    853: 
                    854: #endif /* not HAVE_SELECT */
                    855: 
                    856: #ifdef BSD4_1
                    857: /* VARARGS */
                    858: setpriority ()
                    859: {
                    860:   return 0;
                    861: }
                    862: 
                    863: /*
                    864:  * Partially emulate 4.2 open call.
                    865:  * open is defined as this in 4.1.
                    866:  *
                    867:  * - added by Michael Bloom @ Citicorp/TTI
                    868:  *
                    869:  */
                    870: 
                    871: int
                    872: sys_open (path, oflag, mode)
                    873:      char *path;
                    874:      int oflag, mode;
                    875: {
                    876:   if (oflag & O_CREAT) 
                    877:     return creat (path, mode);
                    878:   else
                    879:     return open (path, oflag);
                    880: }
                    881: 
                    882: init_sigio ()
                    883: {
                    884:   if (noninteractive)
                    885:     return;
                    886:   lmode =  LINTRUP | lmode;
                    887:   ioctl (0, TIOCLSET, &lmode);
                    888: }
                    889: 
                    890: reset_sigio ()
                    891: {
                    892:   if (noninteractive)
                    893:     return;
                    894:   lmode = ~LINTRUP & lmode;
                    895:   ioctl (0, TIOCLSET, &lmode);
                    896: }
                    897: 
                    898: request_sigio ()
                    899: {
                    900:   sigrelse (SIGTINT);
                    901: }
                    902: 
                    903: unrequest_sigio ()
                    904: {
                    905:   sighold (SIGTINT);
                    906: }
                    907: 
                    908: /* still inside #ifdef BSD4_1 */
                    909: #ifdef subprocesses
                    910: 
                    911: int sigheld; /* Mask of held signals */
                    912: 
                    913: sigholdx (signum)
                    914:      int signum;
                    915: {
                    916:   sigheld |= sigbit (signum);
                    917:   sighold (signum);
                    918: }
                    919: 
                    920: sigisheld (signum)
                    921:      int signum;
                    922: {
                    923:   sigheld |= sigbit (signum);
                    924: }
                    925: 
                    926: sigunhold (signum)
                    927:      int signum;
                    928: {
                    929:   sigheld &= ~sigbit (signum);
                    930:   sigrelse (signum);
                    931: }
                    932: 
                    933: sigfree ()    /* Free all held signals */
                    934: {
                    935:   int i;
                    936:   for (i = 0; i < NSIG; i++)
                    937:     if (sigheld & sigbit (i))
                    938:       sigrelse (i);
                    939:   sigheld = 0;
                    940: }
                    941: 
                    942: sigbit (i)
                    943: {
                    944:   return 1 << (i - 1);
                    945: }
                    946: #endif /* subprocesses */
                    947: #endif /* BSD4_1 */
                    948: 
                    949: #ifndef BSTRING
                    950: 
                    951: void
                    952: bzero (b, length)
                    953:      register char *b;
                    954:      register int length;
                    955: {
                    956:   while (length-- > 0)
                    957:     *b++ = 0;
                    958: }
                    959: 
                    960: void 
                    961: bcopy (b1, b2, length)
                    962:      register char *b1;
                    963:      register char *b2;
                    964:      register int length;
                    965: {
                    966:   while (length-- > 0)
                    967:     *b2++ = *b1++;
                    968: }
                    969: 
                    970: int
                    971: bcmp (b1, b2, length)  /* This could be a macro! */
                    972:      register char *b1;
                    973:      register char *b2;
                    974:      register int length;
                    975: {
                    976:   while (length-- > 0)
                    977:     if (*b1++ != *b2++)
                    978:       return 1;
                    979: 
                    980:   return 0;
                    981: }
                    982: #endif /* not BSTRING */
                    983: 
                    984: #if defined (BSD4_1) || defined (USG)
                    985: 
                    986: /*
                    987:  *     The BSD random(3) returns numbers in the range of
                    988:  *     0 to 2e31 - 1.  The USG rand(3C) returns numbers in the
                    989:  *     range of 0 to 2e15 - 1.  This is probably not significant
                    990:  *     in this usage.
                    991:  */
                    992:   
                    993: long
                    994: random ()
                    995: {
                    996:   return (rand ());
                    997: }
                    998: 
                    999: srandom (arg)
                   1000:      int arg;
                   1001: {
                   1002:   srand (arg);
                   1003: }
                   1004: 
                   1005: #endif /* bsd4.1 or any USG */
                   1006: 
                   1007: #ifdef USG
                   1008: /*
                   1009:  *     All of the following are for USG.
                   1010:  *
                   1011:  *     On USG systems the system calls are interruptable by signals
                   1012:  *     that the user program has elected to catch.  Thus the system call
                   1013:  *     must be retried in these cases.  To handle this without massive
                   1014:  *     changes in the source code, we remap the standard system call names
                   1015:  *     to names for our own functions in sysdep.c that do the system call
                   1016:  *     with retries.  Actually, for portability reasons, it is good
                   1017:  *     programming practice, as this example shows, to limit all actual
                   1018:  *     system calls to a single occurance in the source.  Sure, this
                   1019:  *     adds an extra level of function call overhead but it is almost
                   1020:  *     always negligible.   Fred Fish, Unisoft Systems Inc.
                   1021:  */
                   1022: 
                   1023: char *sys_siglist[NSIG + 1] =
                   1024: {
                   1025:   "bogus signal",                      /* 0 */
                   1026:   "hangup",                            /* 1  SIGHUP */
                   1027:   "interrupt",                         /* 2  SIGINT */
                   1028:   "quit",                              /* 3  SIGQUIT */
                   1029:   "illegal instruction",               /* 4  SIGILL */
                   1030:   "trace trap",                                /* 5  SIGTRAP */
                   1031:   "IOT instruction",                   /* 6  SIGIOT */
                   1032:   "EMT instruction",                   /* 7  SIGEMT */
                   1033:   "floating point exception",          /* 8  SIGFPE */
                   1034:   "kill",                              /* 9  SIGKILL */
                   1035:   "bus error",                         /* 10 SIGBUS */
                   1036:   "segmentation violation",            /* 11 SIGSEGV */
                   1037:   "bad argument to system call",       /* 12 SIGSYS */
                   1038:   "write on a pipe with no one to read it", /* 13 SIGPIPE */
                   1039:   "alarm clock",                       /* 14 SIGALRM */
                   1040:   "software termination signum",       /* 15 SIGTERM */
                   1041:   "user defined signal 1",             /* 16 SIGUSR1 */
                   1042:   "user defined signal 2",             /* 17 SIGUSR2 */
                   1043:   "death of a child",                  /* 18 SIGCLD */
                   1044:   "power-fail restart",                        /* 19 SIGPWR */
                   1045:   0
                   1046:   };
                   1047: 
                   1048: int
                   1049: sys_read (fildes, buf, nbyte)
                   1050:      int fildes;
                   1051:      char *buf;
                   1052:      unsigned int nbyte;
                   1053: {
                   1054:   register int rtnval;
                   1055:   
                   1056:   while ((rtnval = read (fildes, buf, nbyte)) == -1 && errno == EINTR);
                   1057:   return (rtnval);
                   1058: }
                   1059: 
                   1060: int
                   1061: /* VARARGS 2 */
                   1062: sys_open (path, oflag, mode)
                   1063:      char *path;
                   1064:      int oflag, mode;
                   1065: {
                   1066:   register int rtnval;
                   1067:   
                   1068:   while ((rtnval = open (path, oflag, mode)) == -1 && errno == EINTR);
                   1069:   return (rtnval);
                   1070: }
                   1071: 
                   1072: int
                   1073: sys_write (fildes, buf, nbyte)
                   1074:      int fildes;
                   1075:      char *buf;
                   1076:      unsigned int nbyte;
                   1077: {
                   1078:   register int rtnval;
                   1079: 
                   1080:   while ((rtnval = write (fildes, buf, nbyte)) == -1 && errno == EINTR);
                   1081:   return (rtnval);
                   1082: }
                   1083: 
                   1084: /*
                   1085:  *     Warning, this function may not duplicate 4.2 action properly
                   1086:  *     under error conditions.
                   1087:  */
                   1088: 
                   1089: #ifndef MAXPATHLEN
                   1090: /* In 4.1, param.h fails to define this.  */
                   1091: #define MAXPATHLEN 1024
                   1092: #endif
                   1093: 
                   1094: char *
                   1095: getwd (pathname)
                   1096:      char *pathname;
                   1097: {
                   1098:   extern char *getcwd ();
                   1099: 
                   1100:   return (getcwd (pathname, MAXPATHLEN));
                   1101: }
                   1102: 
                   1103: /*
                   1104:  *     Emulate rename using unlink/link.  Note that this is
                   1105:  *     only partially correct.  Also, doesn't enforce restriction
                   1106:  *     that files be of same type (regular->regular, dir->dir, etc).
                   1107:  */
                   1108: 
                   1109: rename (from, to)
                   1110:      char *from;
                   1111:      char *to;
                   1112: {
                   1113:   if (access (from, 0) == 0)
                   1114:     {
                   1115:       unlink (to);
                   1116:       if (link (from, to) == 0)
                   1117:        if (unlink (from) == 0)
                   1118:          return (0);
                   1119:     }
                   1120:   return (-1);
                   1121: }
                   1122: 
                   1123: /* VARARGS */
                   1124: setpriority ()
                   1125: {
                   1126:   return (0);
                   1127: }
                   1128: 
                   1129: #ifndef HPUX
                   1130: 
                   1131: /*
                   1132:  *     Substitute fork(2) for vfork(2) on USG flavors.
                   1133:  */
                   1134: 
                   1135: vfork ()
                   1136: {
                   1137:   return (fork ());
                   1138: }
                   1139: 
                   1140: /*
                   1141:  *     Emulate BSD dup2(2).  First close newd if it already exists.
                   1142:  *     Then, attempt to dup oldd.  If not successful, call dup2 recursively
                   1143:  *     until we are, then close the unsuccessful ones.
                   1144:  */
                   1145: 
                   1146: dup2 (oldd, newd)
                   1147:      int oldd;
                   1148:      int newd;
                   1149: {
                   1150:   register int fd;
                   1151:   
                   1152:   close (newd);
                   1153:   while ((fd = dup (oldd)) != newd) {
                   1154:     dup2 (oldd, newd);
                   1155:     close (fd);
                   1156:   }
                   1157: }
                   1158: 
                   1159: /*
                   1160:  *     Gettimeofday.  Simulate as much as possible.  Only accurate
                   1161:  *     to nearest second.  Emacs doesn't use tzp so ignore it for now.
                   1162:  *     Only needed when subprocesses are defined.
                   1163:  */
                   1164: 
                   1165: #if defined(subprocesses) && !defined(STRIDE) && defined(HAVE_TIMEVAL)
                   1166:  
                   1167: /* ARGSUSED */
                   1168: gettimeofday (tp, tzp)
                   1169:      struct timeval *tp;
                   1170:      struct timezone *tzp;
                   1171: {
                   1172:   extern long time ();
                   1173: 
                   1174:   tp->tv_sec = time ((long *)0);    
                   1175:   tp->tv_usec = 0;
                   1176: }
                   1177:  
                   1178: #endif /* subprocess && ~STRIDE && HAVE_TIMEVAL */
                   1179: #endif /* not HPUX */ 
                   1180:   
                   1181: /*
                   1182:  *     This function will go away as soon as all the stubs fixed.  (fnf)
                   1183:  */
                   1184: 
                   1185: croak (badfunc)
                   1186:      char *badfunc;
                   1187: {
                   1188:   printf ("%s not yet implemented\r\n", badfunc);
                   1189:   reset_sys_modes ();
                   1190:   exit (1);
                   1191: }
                   1192: 
                   1193: #endif /* USG */
                   1194: 
                   1195: /* Directory routines for systems that don't have them. */
                   1196: 
                   1197: #ifdef NONSYSTEM_DIR_LIBRARY
                   1198: 
                   1199: DIR *
                   1200: opendir (filename)
                   1201:      char *filename;   /* name of directory */
                   1202: {
                   1203:   register DIR *dirp;          /* -> malloc'ed storage */
                   1204:   register int fd;             /* file descriptor for read */
                   1205:   struct stat sbuf;            /* result of fstat() */
                   1206: 
                   1207:   fd = sys_open (filename, 0);
                   1208:   if (fd < 0)
                   1209:     return 0;
                   1210: 
                   1211:   if (fstat (fd, &sbuf) < 0
                   1212:       || (sbuf.st_mode & S_IFMT) != S_IFDIR
                   1213:       || (dirp = (DIR *) malloc (sizeof (DIR))) == 0)
                   1214:     {
                   1215:       close (fd);
                   1216:       return 0;                /* bad luck today */
                   1217:     }
                   1218: 
                   1219:   dirp->dd_fd = fd;
                   1220:   dirp->dd_loc = dirp->dd_size = 0;    /* refill needed */
                   1221: 
                   1222:   return dirp;
                   1223: }
                   1224: 
                   1225: void
                   1226: closedir (dirp)
                   1227:      register DIR *dirp;               /* stream from opendir() */
                   1228: {
                   1229:   close (dirp->dd_fd);
                   1230:   free ((char *) dirp);
                   1231: }
                   1232: 
                   1233: 
                   1234: #define DIRSIZ 14
                   1235: struct olddir
                   1236:   {
                   1237:     ino_t od_ino;              /* inode */
                   1238:     char od_name[DIRSIZ];      /* filename */
                   1239:   };
                   1240: 
                   1241: struct direct dir_static;      /* simulated directory contents */
                   1242: 
                   1243: struct direct *
                   1244: readdir (dirp)
                   1245:      register DIR *dirp;       /* stream from opendir() */
                   1246: {
                   1247:   register struct olddir *dp;  /* -> directory data */
                   1248: 
                   1249:   for ( ; ; )
                   1250:     {
                   1251:       if (dirp->dd_loc >= dirp->dd_size)
                   1252:        dirp->dd_loc = dirp->dd_size = 0;
                   1253: 
                   1254:       if (dirp->dd_size == 0   /* refill buffer */
                   1255:          && (dirp->dd_size = sys_read (dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
                   1256:        return 0;
                   1257: 
                   1258:       dp = (struct olddir *) &dirp->dd_buf[dirp->dd_loc];
                   1259:       dirp->dd_loc += sizeof (struct olddir);
                   1260: 
                   1261:       if (dp->od_ino != 0)     /* not deleted entry */
                   1262:        {
                   1263:          dir_static.d_ino = dp->od_ino;
                   1264:          strncpy (dir_static.d_name, dp->od_name, DIRSIZ);
                   1265:          dir_static.d_name[DIRSIZ] = '\0';
                   1266:          dir_static.d_namlen = strlen (dir_static.d_name);
                   1267:          dir_static.d_reclen = sizeof (struct direct)
                   1268:            - MAXNAMLEN + 3
                   1269:              + dir_static.d_namlen - dir_static.d_namlen % 4;
                   1270:          return &dir_static;   /* -> simulated structure */
                   1271:        }
                   1272:     }
                   1273: }
                   1274: 
                   1275: #endif /* NONSYSTEM_DIR_LIBRARY */

unix.superglobalmegacorp.com

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