Annotation of 43BSD/contrib/emacs/src/sysdep.c, revision 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.