(linenum→info "unix/slp.c:2238")

emacs/22.1/src/sysdep.c

    1: /* Interfaces to system-dependent kernel and library entries.
    2:    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1999, 2000, 2001,
    3:                  2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    4: 
    5: This file is part of GNU Emacs.
    6: 
    7: GNU Emacs is free software; you can redistribute it and/or modify
    8: it under the terms of the GNU General Public License as published by
    9: the Free Software Foundation; either version 2, or (at your option)
   10: any later version.
   11: 
   12: GNU Emacs is distributed in the hope that it will be useful,
   13: but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: GNU General Public License for more details.
   16: 
   17: You should have received a copy of the GNU General Public License
   18: along with GNU Emacs; see the file COPYING.  If not, write to
   19: the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   20: Boston, MA 02110-1301, USA.  */
   21: 
   22: #ifdef HAVE_CONFIG_H
   23: #include <config.h>
   24: #endif
   25: 
   26: #include <signal.h>
   27: #include <stdio.h>
   28: #include <setjmp.h>
   29: #ifdef HAVE_UNISTD_H
   30: #include <unistd.h>
   31: #endif
   32: #include "lisp.h"
   33: /* Including stdlib.h isn't necessarily enough to get srandom
   34:    declared, e.g. without __USE_XOPEN_EXTENDED with glibc 2.  */
   35: #ifdef HAVE_RANDOM
   36: #if 0 /* It turns out that defining _OSF_SOURCE in osf5-0.h gets
   37:          random prototyped as returning `int'.  It looks to me as
   38:          though the best way to DTRT is to prefer the rand48 functions
   39:          (per libc.info).  -- fx */
   40: extern long int random P_ ((void));
   41: #endif
   42: #if 0 /* Don't prototype srandom; it takes an unsigned argument on
   43:          some systems, and an unsigned long on others, like FreeBSD
   44:          4.1.  */
   45: extern void srandom P_ ((unsigned int));
   46: #endif
   47: #endif
   48: 
   49: #include "blockinput.h"
   50: 
   51: #ifdef MAC_OS8
   52: #include <sys/param.h>
   53: 
   54: #ifndef subprocesses
   55: /* Nonzero means delete a process right away if it exits (process.c).  */
   56: static int delete_exited_processes;
   57: #endif
   58: #endif  /* MAC_OS8 */
   59: 
   60: #ifdef WINDOWSNT
   61: #define read sys_read
   62: #define write sys_write
   63: #include <windows.h>
   64: #ifndef NULL
   65: #define NULL 0
   66: #endif
   67: #endif /* not WINDOWSNT */
   68: 
   69: /* Does anyone other than VMS need this? */
   70: #ifndef fwrite
   71: #define sys_fwrite fwrite
   72: #else
   73: #undef fwrite
   74: #endif
   75: 
   76: #include <sys/types.h>
   77: #include <sys/stat.h>
   78: #include <errno.h>
   79: 
   80: #ifdef HAVE_SETPGID
   81: #if !defined (USG) || defined (BSD_PGRPS)
   82: #undef setpgrp
   83: #define setpgrp setpgid
   84: #endif
   85: #endif
   86: 
   87: /* Get SI_SRPC_DOMAIN, if it is available.  */
   88: #ifdef HAVE_SYS_SYSTEMINFO_H
   89: #include <sys/systeminfo.h>
   90: #endif
   91: 
   92: #ifdef MSDOS    /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */
   93: #include <dos.h>
   94: #include "dosfns.h"
   95: #include "msdos.h"
   96: #include <sys/param.h>
   97: 
   98: #if __DJGPP__ > 1
   99: extern int etext;
  100: extern unsigned start __asm__ ("start");
  101: #endif
  102: #endif
  103: 
  104: #ifndef USE_CRT_DLL
  105: #ifndef errno
  106: extern int errno;
  107: #endif
  108: #endif
  109: 
  110: #ifdef VMS
  111: #include <rms.h>
  112: #include <ttdef.h>
  113: #include <tt2def.h>
  114: #include <iodef.h>
  115: #include <ssdef.h>
  116: #include <descrip.h>
  117: #include <fibdef.h>
  118: #include <atrdef.h>
  119: #include <ctype.h>
  120: #include <string.h>
  121: #ifdef __GNUC__
  122: #include <sys/file.h>
  123: #else
  124: #include <file.h>
  125: #endif
  126: #undef F_SETFL
  127: #ifndef RAB$C_BID
  128: #include <rab.h>
  129: #endif
  130: #define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */
  131: #endif /* VMS */
  132: 
  133: #ifndef VMS
  134: #include <sys/file.h>
  135: #endif /* not VMS */
  136: 
  137: #ifdef HAVE_FCNTL_H
  138: #include <fcntl.h>
  139: #endif
  140: 
  141: #ifndef MSDOS
  142: #include <sys/ioctl.h>
  143: #endif
  144: 
  145: #include "systty.h"
  146: #include "syswait.h"
  147: 
  148: #ifdef BROKEN_TIOCGWINSZ
  149: #undef TIOCGWINSZ
  150: #undef TIOCSWINSZ
  151: #endif
  152: 
  153: #if defined (USG) || defined (DGUX)
  154: #include <sys/utsname.h>
  155: #ifndef MEMORY_IN_STRING_H
  156: #include <memory.h>
  157: #endif
  158: #if defined (TIOCGWINSZ) || defined (ISC4_0)
  159: #ifdef NEED_SIOCTL
  160: #include <sys/sioctl.h>
  161: #endif
  162: #ifdef NEED_PTEM_H
  163: #include <sys/stream.h>
  164: #include <sys/ptem.h>
  165: #endif
  166: #endif /* TIOCGWINSZ or ISC4_0 */
  167: #endif /* USG or DGUX */
  168: 
  169: extern int quit_char;
  170: 
  171: #include "keyboard.h"
  172: #include "frame.h"
  173: #include "window.h"
  174: #include "termhooks.h"
  175: #include "termchar.h"
  176: #include "termopts.h"
  177: #include "dispextern.h"
  178: #include "process.h"
  179: 
  180: #ifdef WINDOWSNT
  181: #include <direct.h>
  182: /* In process.h which conflicts with the local copy.  */
  183: #define _P_WAIT 0
  184: int _CRTAPI1 _spawnlp (int, const char *, const char *, ...);
  185: int _CRTAPI1 _getpid (void);
  186: extern char *getwd (char *);
  187: #endif
  188: 
  189: #ifdef NONSYSTEM_DIR_LIBRARY
  190: #include "ndir.h"
  191: #endif /* NONSYSTEM_DIR_LIBRARY */
  192: 
  193: #include "syssignal.h"
  194: #include "systime.h"
  195: #ifdef HAVE_UTIME_H
  196: #include <utime.h>
  197: #endif
  198: 
  199: #ifndef HAVE_UTIMES
  200: #ifndef HAVE_STRUCT_UTIMBUF
  201: /* We want to use utime rather than utimes, but we couldn't find the
  202:    structure declaration.  We'll use the traditional one.  */
  203: struct utimbuf {
  204:   long actime;
  205:   long modtime;
  206: };
  207: #endif
  208: #endif
  209: 
  210: /* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits.  */
  211: #ifndef LPASS8
  212: #define LPASS8 0
  213: #endif
  214: 
  215: #ifdef BSD4_1
  216: #define LNOFLSH 0100000
  217: #endif
  218: 
  219: static int baud_convert[] =
  220: #ifdef BAUD_CONVERT
  221:   BAUD_CONVERT;
  222: #else
  223:   {
  224:     0, 50, 75, 110, 135, 150, 200, 300, 600, 1200,
  225:     1800, 2400, 4800, 9600, 19200, 38400
  226:   };
  227: #endif
  228: 
  229: #ifdef HAVE_SPEED_T
  230: #include <termios.h>
  231: #else
  232: #if defined (HAVE_LIBNCURSES) && ! defined (NCURSES_OSPEED_T)
  233: #else
  234: #if defined (HAVE_TERMIOS_H) && defined (GNU_LINUX)
  235: #include <termios.h>
  236: #endif
  237: #endif
  238: #endif
  239: 
  240: int emacs_ospeed;
  241: 
  242: /* The file descriptor for Emacs's input terminal.
  243:    Under Unix, this is normally zero except when using X;
  244:    under VMS, we place the input channel number here.  */
  245: int input_fd;
  246: 
  247: void croak P_ ((char *)) NO_RETURN;
  248: 
  249: #ifdef AIXHFT
  250: void hft_init ();
  251: void hft_reset ();
  252: #endif
  253: 
  254: /* Temporary used by `sigblock' when defined in terms of signprocmask.  */
  255: 
  256: SIGMASKTYPE sigprocmask_set;
  257: 
  258: 
  259: #if !defined (HAVE_GET_CURRENT_DIR_NAME) || defined (BROKEN_GET_CURRENT_DIR_NAME)
  260: 
  261: /* Return the current working directory.  Returns NULL on errors.
  262:    Any other returned value must be freed with free. This is used
  263:    only when get_current_dir_name is not defined on the system.  */
  264: char*
  265: get_current_dir_name ()
  266: {
  267:   char *buf;
  268:   char *pwd;
  269:   struct stat dotstat, pwdstat;
  270:   /* If PWD is accurate, use it instead of calling getwd.  PWD is
  271:      sometimes a nicer name, and using it may avoid a fatal error if a
  272:      parent directory is searchable but not readable.  */
  273:     if ((pwd = getenv ("PWD")) != 0
  274:       && (IS_DIRECTORY_SEP (*pwd) || (*pwd && IS_DEVICE_SEP (pwd[1])))
  275:       && stat (pwd, &pwdstat) == 0
  276:       && stat (".", &dotstat) == 0
  277:       && dotstat.st_ino == pwdstat.st_ino
  278:       && dotstat.st_dev == pwdstat.st_dev
  279: #ifdef MAXPATHLEN
  280:       && strlen (pwd) < MAXPATHLEN
  281: #endif
  282:       )
  283:     {
  284:       buf = (char *) malloc (strlen (pwd) + 1);
  285:       if (!buf)
  286:         return NULL;
  287:       strcpy (buf, pwd);
  288:     }
  289: #ifdef HAVE_GETCWD
  290:   else
  291:     {
  292:       size_t buf_size = 1024;
  293:       buf = (char *) malloc (buf_size);
  294:       if (!buf)
  295:         return NULL;
  296:       for (;;)
  297:         {
  298:           if (getcwd (buf, buf_size) == buf)
  299:             break;
  300:           if (errno != ERANGE)
  301:             {
  302:               int tmp_errno = errno;
  303:               free (buf);
  304:               errno = tmp_errno;
  305:               return NULL;
  306:             }
  307:           buf_size *= 2;
  308:           buf = (char *) realloc (buf, buf_size);
  309:           if (!buf)
  310:             return NULL;
  311:         }
  312:     }
  313: #else
  314:   else
  315:     {
  316:       /* We need MAXPATHLEN here.  */
  317:       buf = (char *) malloc (MAXPATHLEN + 1);
  318:       if (!buf)
  319:         return NULL;
  320:       if (getwd (buf) == NULL)
  321:         {
  322:           int tmp_errno = errno;
  323:           free (buf);
  324:           errno = tmp_errno;
  325:           return NULL;
  326:         }
  327:     }
  328: #endif
  329:   return buf;
  330: }
  331: #endif
  332: 
  333: ^L
  334: /* Specify a different file descriptor for further input operations.  */
  335: 
  336: void
  337: change_input_fd (fd)
  338:      int fd;
  339: {
  340:   input_fd = fd;
  341: }
  342: 
  343: /* Discard pending input on descriptor input_fd.  */
  344: 
  345: void
  346: discard_tty_input ()
  347: {
  348: #ifndef WINDOWSNT
  349:   struct emacs_tty buf;
  350: 
  351:   if (noninteractive)
  352:     return;
  353: 
  354:   /* Discarding input is not safe when the input could contain
  355:      replies from the X server.  So don't do it.  */
  356:   if (read_socket_hook)
  357:     return;
  358: 
  359: #ifdef VMS
  360:   end_kbd_input ();
  361:   SYS$QIOW (0, input_fd, IO$_READVBLK|IO$M_PURGE, input_iosb, 0, 0,
  362:             &buf.main, 0, 0, terminator_mask, 0, 0);
  363:   queue_kbd_input ();
  364: #else /* not VMS */
  365: #ifdef APOLLO
  366:   {
  367:     int zero = 0;
  368:     ioctl (input_fd, TIOCFLUSH, &zero);
  369:   }
  370: #else /* not Apollo */
  371: #ifdef MSDOS    /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */
  372:   while (dos_keyread () != -1)
  373:     ;
  374: #else /* not MSDOS */
  375:   EMACS_GET_TTY (input_fd, &buf);
  376:   EMACS_SET_TTY (input_fd, &buf, 0);
  377: #endif /* not MSDOS */
  378: #endif /* not Apollo */
  379: #endif /* not VMS */
  380: #endif /* not WINDOWSNT */
  381: }
  382: 
  383: #ifdef SIGTSTP
  384: 
  385: /* Arrange for character C to be read as the next input from
  386:    the terminal.  */
  387: 
  388: void
  389: #ifdef PROTOTYPES
  390: stuff_char (char c)
  391: #else
  392: stuff_char (c)
  393:      char c;
  394: #endif
  395: {
  396:   if (read_socket_hook)
  397:     return;
  398: 
  399: /* Should perhaps error if in batch mode */
  400: #ifdef TIOCSTI
  401:   ioctl (input_fd, TIOCSTI, &c);
  402: #else /* no TIOCSTI */
  403:   error ("Cannot stuff terminal input characters in this version of Unix");
  404: #endif /* no TIOCSTI */
  405: }
  406: 
  407: #endif /* SIGTSTP */
  408: ^L
  409: void
  410: init_baud_rate ()
  411: {
  412:   if (noninteractive)
  413:     emacs_ospeed = 0;
  414:   else
  415:     {
  416: #ifdef INIT_BAUD_RATE
  417:       INIT_BAUD_RATE ();
  418: #else
  419: #ifdef DOS_NT
  420:     emacs_ospeed = 15;
  421: #else  /* not DOS_NT */
  422: #ifdef VMS
  423:       struct sensemode sg;
  424: 
  425:       SYS$QIOW (0, input_fd, IO$_SENSEMODE, &sg, 0, 0,
  426:                 &sg.class, 12, 0, 0, 0, 0 );
  427:       emacs_ospeed = sg.xmit_baud;
  428: #else /* not VMS */
  429: #ifdef HAVE_TERMIOS
  430:       struct termios sg;
  431: 
  432:       sg.c_cflag = B9600;
  433:       tcgetattr (input_fd, &sg);
  434:       emacs_ospeed = cfgetospeed (&sg);
  435: #if defined (USE_GETOBAUD) && defined (getobaud)
  436:       /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */
  437:       if (emacs_ospeed == 0)
  438:         emacs_ospeed = getobaud (sg.c_cflag);
  439: #endif
  440: #else /* neither VMS nor TERMIOS */
  441: #ifdef HAVE_TERMIO
  442:       struct termio sg;
  443: 
  444:       sg.c_cflag = B9600;
  445: #ifdef HAVE_TCATTR
  446:       tcgetattr (input_fd, &sg);
  447: #else
  448:       ioctl (input_fd, TCGETA, &sg);
  449: #endif
  450:       emacs_ospeed = sg.c_cflag & CBAUD;
  451: #else /* neither VMS nor TERMIOS nor TERMIO */
  452:       struct sgttyb sg;
  453: 
  454:       sg.sg_ospeed = B9600;
  455:       if (ioctl (input_fd, TIOCGETP, &sg) < 0)
  456:         abort ();
  457:       emacs_ospeed = sg.sg_ospeed;
  458: #endif /* not HAVE_TERMIO */
  459: #endif /* not HAVE_TERMIOS */
  460: #endif /* not VMS */
  461: #endif /* not DOS_NT */
  462: #endif /* not INIT_BAUD_RATE */
  463:     }
  464: 
  465:   baud_rate = (emacs_ospeed < sizeof baud_convert / sizeof baud_convert[0]
  466:                ? baud_convert[emacs_ospeed] : 9600);
  467:   if (baud_rate == 0)
  468:     baud_rate = 1200;
  469: }
  470: 
  471: /*ARGSUSED*/
  472: void
  473: set_exclusive_use (fd)
  474:      int fd;
  475: {
  476: #ifdef FIOCLEX
  477:   ioctl (fd, FIOCLEX, 0);
  478: #endif
  479:   /* Ok to do nothing if this feature does not exist */
  480: }
  481: ^L
  482: #ifndef subprocesses
  483: 
  484: wait_without_blocking ()
  485: {
  486: #ifdef BSD_SYSTEM
  487:   wait3 (0, WNOHANG | WUNTRACED, 0);
  488: #else
  489:   croak ("wait_without_blocking");
  490: #endif
  491:   synch_process_alive = 0;
  492: }
  493: 
  494: #endif /* not subprocesses */
  495: 
  496: int wait_debugging;   /* Set nonzero to make following function work under dbx
  497:                          (at least for bsd).  */
  498: 
  499: SIGTYPE
  500: wait_for_termination_signal ()
  501: {}
  502: 
  503: /* Wait for subprocess with process id `pid' to terminate and
  504:    make sure it will get eliminated (not remain forever as a zombie) */
  505: 
  506: void
  507: wait_for_termination (pid)
  508:      int pid;
  509: {
  510:   while (1)
  511:     {
  512: #ifdef subprocesses
  513: #ifdef VMS
  514:       int status;
  515: 
  516:       status = SYS$FORCEX (&pid, 0, 0);
  517:       break;
  518: #else /* not VMS */
  519: #if defined (BSD_SYSTEM) || (defined (HPUX) && !defined (HPUX_5))
  520:       /* Note that kill returns -1 even if the process is just a zombie now.
  521:          But inevitably a SIGCHLD interrupt should be generated
  522:          and child_sig will do wait3 and make the process go away. */
  523:       /* There is some indication that there is a bug involved with
  524:          termination of subprocesses, perhaps involving a kernel bug too,
  525:          but no idea what it is.  Just as a hunch we signal SIGCHLD to see
  526:          if that causes the problem to go away or get worse.  */
  527:       sigsetmask (sigmask (SIGCHLD));
  528:       if (0 > kill (pid, 0))
  529:         {
  530:           sigsetmask (SIGEMPTYMASK);
  531:           kill (getpid (), SIGCHLD);
  532:           break;
  533:         }
  534:       if (wait_debugging)
  535:         sleep (1);
  536:       else
  537:         sigpause (SIGEMPTYMASK);
  538: #else /* not BSD_SYSTEM, and not HPUX version >= 6 */
  539: #if defined (UNIPLUS)
  540:       if (0 > kill (pid, 0))
  541:         break;
  542:       wait (0);
  543: #else /* neither BSD_SYSTEM nor UNIPLUS: random sysV */
  544: #ifdef POSIX_SIGNALS    /* would this work for GNU/Linux as well? */
  545:       sigblock (sigmask (SIGCHLD));
  546:       errno = 0;
  547:       if (kill (pid, 0) == -1 && errno == ESRCH)
  548:         {
  549:           sigunblock (sigmask (SIGCHLD));
  550:           break;
  551:         }
  552: 
  553:       sigsuspend (&empty_mask);
  554: #else /* not POSIX_SIGNALS */
  555: #ifdef HAVE_SYSV_SIGPAUSE
  556:       sighold (SIGCHLD);
  557:       if (0 > kill (pid, 0))
  558:         {
  559:           sigrelse (SIGCHLD);
  560:           break;
  561:         }
  562:       sigpause (SIGCHLD);
  563: #else /* not HAVE_SYSV_SIGPAUSE */
  564: #ifdef WINDOWSNT
  565:       wait (0);
  566:       break;
  567: #else /* not WINDOWSNT */<