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 */

Defined functions

child_setup_tty defined in line 262; used 1 times
closedir defined in line 1225; used 4 times
croak defined in line 1185; used 3 times
discard_tty_input defined in line 118; used 1 times
end_of_data defined in line 662; never used
end_of_text defined in line 646; never used
flush_pending_output defined in line 574; used 2 times
get_screen_size defined in line 502; used 1 times
get_system_name defined in line 686; used 1 times
getwd defined in line 1094; used 2 times
init_baud_rate defined in line 144; used 1 times
init_sigio defined in line 882; used 2 times
opendir defined in line 1199; used 4 times
random defined in line 993; used 2 times
read_input_waiting defined in line 841; used 2 times
readdir defined in line 1243; used 4 times
rename defined in line 1109; used 1 times
request_sigio defined in line 898; used 4 times
reset_sigio defined in line 890; used 4 times
select_alarm defined in line 712; used 1 times
set_exclusive_use defined in line 160; used 1 times
setpgrp_of_tty defined in line 290; used 1 times
sigbit defined in line 942; used 6 times
sigfree defined in line 933; never used
sigholdx defined in line 913; never used
sigisheld defined in line 920; used 2 times
sigunhold defined in line 926; used 1 times
srandom defined in line 999; used 2 times
start_of_data defined in line 628; used 7 times
start_of_text defined in line 591; used 5 times
stuff_char defined in line 131; used 3 times
sys_open defined in line 1060; never used
sys_read defined in line 1048; never used
sys_write defined in line 1072; never used
tabs_safe_p defined in line 489; used 1 times
unrequest_sigio defined in line 903; used 6 times
wait_without_blocking defined in line 171; used 1 times

Defined variables

_sobuf defined in line 365; used 1 times
baud_convert defined in line 110; used 3 times
dir_static defined in line 1241; used 9 times
get_system_name_name defined in line 680; used 2 times
lmode defined in line 354; used 8 times
old_fcntl_flags defined in line 313; used 4 times
old_fcntl_owner defined in line 346; used 2 times
old_lmode defined in line 352; used 3 times
old_ltchars defined in line 351; used 2 times
old_tchars defined in line 350; used 2 times
select_alarmed defined in line 710; used 4 times
sigheld defined in line 911; used 5 times
sys_siglist defined in line 1023; never used
term_initted defined in line 343; used 2 times
wait_debugging defined in line 182; used 2 times

Defined struct's

olddir defined in line 1235; used 6 times

Defined macros

DIRSIZ defined in line 1234; used 3 times
LLITOUT defined in line 70; used 2 times
LNOFLSH defined in line 466; used 1 times
LPASS8 defined in line 462; used 2 times
MAXPATHLEN defined in line 1091; used 2 times
OSPEED defined in line 90; used 1 times
SELECT_PAUSE defined in line 709; used 3 times
SIGCHLD defined in line 107; used 6 times
TABS_OK defined in line 91; used 1 times
TERMINAL defined in line 89; used 6 times
TIOCGETP defined in line 86; used 5 times
TIOCGWINSZ defined in line 508; used 3 times
TIOCSETN defined in line 87; used 3 times
TIOCSETP defined in line 88; used 1 times
sys_open defined in line 41; used 1 times
sys_read defined in line 33; used 1 times
sys_write defined in line 34; never used
winsize defined in line 509; never used
ws_col defined in line 511; used 1 times
ws_row defined in line 510; used 1 times
Last modified: 1986-03-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5517
Valid CSS Valid XHTML 1.0 Strict