X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/039f26a48fc065b90f18a92a884df46c25d92057..441f6399d885deb5acb8d37f1aac306ebef0c50a:/src/sysdep.c diff --git a/src/sysdep.c b/src/sysdep.c index cda2b8f3a4..7c8a072eb9 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -1,11 +1,11 @@ /* Interfaces to system-dependent kernel and library entries. - Copyright (C) 1985, 1986, 1987, 1988, 1993 Free Software Foundation, Inc. + Copyright (C) 1985, 86, 87, 88, 93, 94 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 1, or (at your option) +the Free Software Foundation; either version 2, or (at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, @@ -21,7 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include -#include "config.h" +#include #include "lisp.h" #include "blockinput.h" #undef NULL @@ -40,6 +40,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #undef read #undef write +#ifdef WINDOWSNT +#define read _read +#define write _write +#include +extern int errno; +#endif /* not WINDOWSNT */ + #ifndef close #define sys_close close #else @@ -59,16 +66,24 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #undef fwrite #endif +#ifndef HAVE_H_ERRNO +extern int h_errno; +#endif + #include #include #include #include -extern int errno; -#ifndef VMS -extern char *sys_errlist[]; +#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */ +#include +#include "dosfns.h" +#include "msdos.h" +#include #endif +extern int errno; + #ifdef VMS #include #include @@ -89,7 +104,7 @@ extern char *sys_errlist[]; #ifndef RAB$C_BID #include #endif -#define MAXIOSIZE ( 32 * PAGESIZE ) /* Don't I/O more than 32 blocks at a time */ +#define MAXIOSIZE (32 * PAGESIZE) /* Don't I/O more than 32 blocks at a time */ #endif /* VMS */ #ifndef BSD4_1 @@ -104,21 +119,15 @@ extern char *sys_errlist[]; #endif #endif /* not 4.1 bsd */ -#ifdef BROKEN_FASYNC -/* On some systems (DGUX comes to mind real fast) FASYNC causes - background writes to the terminal to stop all processes in the - process group when invoked under the csh (and probably any shell - with job control). This stops Emacs dead in its tracks when coming - up under X11. */ -#undef FASYNC -#endif - +#ifndef MSDOS #include +#endif #include "systty.h" #include "syswait.h" #ifdef BROKEN_TIOCGWINSZ #undef TIOCGWINSZ +#undef TIOCSWINSZ #endif #ifdef USG @@ -127,7 +136,7 @@ extern char *sys_errlist[]; #ifndef MEMORY_IN_STRING_H #include #endif -#ifdef TIOCGWINSZ +#if defined (TIOCGWINSZ) || defined (ISC4_0) #ifdef NEED_SIOCTL #include #endif @@ -135,7 +144,7 @@ extern char *sys_errlist[]; #include #include #endif -#endif /* TIOCGWINSZ */ +#endif /* TIOCGWINSZ or ISC4_0 */ #endif /* USG */ extern int quit_char; @@ -148,12 +157,43 @@ extern int quit_char; #include "dispextern.h" #include "process.h" +#ifdef WINDOWSNT +#include +/* In process.h which conflicts with the local copy. */ +#define _P_WAIT 0 +int _CRTAPI1 _spawnlp (int, const char *, const char *, ...); +int _CRTAPI1 _getpid (void); +#endif + #ifdef NONSYSTEM_DIR_LIBRARY #include "ndir.h" #endif /* NONSYSTEM_DIR_LIBRARY */ #include "syssignal.h" #include "systime.h" +#ifdef HAVE_UTIME_H +#include +#endif + +#ifndef HAVE_UTIMES +#ifndef HAVE_STRUCT_UTIMBUF +/* We want to use utime rather than utimes, but we couldn't find the + structure declaration. We'll use the traditional one. */ +struct utimbuf { + long actime; + long modtime; +}; +#endif +#endif + +/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */ +#ifndef LPASS8 +#define LPASS8 0 +#endif + +#ifdef BSD4_1 +#define LNOFLSH 0100000 +#endif static int baud_convert[] = #ifdef BAUD_CONVERT @@ -168,13 +208,24 @@ static int baud_convert[] = extern short ospeed; /* The file descriptor for Emacs's input terminal. - Under Unix, this is always left zero; - under VMS, we place the input channel number here. - This allows us to write more code that works for both VMS and Unix. */ -static int input_fd; + Under Unix, this is normally zero except when using X; + under VMS, we place the input channel number here. */ +int input_fd; + +/* Specify a different file descriptor for further input operations. */ + +void +change_input_fd (fd) + int fd; +{ + input_fd = fd; +} + +/* Discard pending input on descriptor input_fd. */ discard_tty_input () { +#ifndef WINDOWSNT struct emacs_tty buf; if (noninteractive) @@ -194,36 +245,51 @@ discard_tty_input () #ifdef APOLLO { int zero = 0; - ioctl (0, TIOCFLUSH, &zero); + ioctl (input_fd, TIOCFLUSH, &zero); } #else /* not Apollo */ +#ifdef MSDOS /* Demacs 1.1.1 91/10/16 HIRANO Satoshi */ + while (dos_keyread () != -1) + ; +#else /* not MSDOS */ EMACS_GET_TTY (input_fd, &buf); EMACS_SET_TTY (input_fd, &buf, 0); +#endif /* not MSDOS */ #endif /* not Apollo */ #endif /* not VMS */ +#endif /* not WINDOWSNT */ } #ifdef SIGTSTP +/* Arrange for character C to be read as the next input from + the terminal. */ + stuff_char (c) char c; { + if (read_socket_hook) + return; + /* Should perhaps error if in batch mode */ #ifdef TIOCSTI - ioctl (0, TIOCSTI, &c); + ioctl (input_fd, TIOCSTI, &c); #else /* no TIOCSTI */ - error ("Cannot stuff terminal input characters in this version of Unix."); + error ("Cannot stuff terminal input characters in this version of Unix"); #endif /* no TIOCSTI */ } #endif /* SIGTSTP */ - + init_baud_rate () { if (noninteractive) ospeed = 0; else { +#ifdef DOS_NT + ospeed = 15; +#else /* not DOS_NT */ #ifdef VMS struct sensemode sg; @@ -234,16 +300,21 @@ init_baud_rate () #ifdef HAVE_TERMIOS struct termios sg; - sg.c_cflag = (sg.c_cflag & ~CBAUD) | B9600; - tcgetattr (0, &sg); + sg.c_cflag = B9600; + tcgetattr (input_fd, &sg); ospeed = cfgetospeed (&sg); +#if defined (USE_GETOBAUD) && defined (getobaud) + /* m88k-motorola-sysv3 needs this (ghazi@noc.rutgers.edu) 9/1/94. */ + if (ospeed == 0) + ospeed = getobaud (sg.c_cflag); +#endif #else /* neither VMS nor TERMIOS */ #ifdef HAVE_TERMIO struct termio sg; - sg.c_cflag = (sg.c_cflag & ~CBAUD) | B9600; + sg.c_cflag = B9600; #ifdef HAVE_TCATTR - tcgetattr (0, &sg); + tcgetattr (input_fd, &sg); #else ioctl (input_fd, TCGETA, &sg); #endif @@ -252,16 +323,17 @@ init_baud_rate () struct sgttyb sg; sg.sg_ospeed = B9600; - if (ioctl (0, TIOCGETP, &sg) < 0) + if (ioctl (input_fd, TIOCGETP, &sg) < 0) abort (); ospeed = sg.sg_ospeed; #endif /* not HAVE_TERMIO */ #endif /* not HAVE_TERMIOS */ #endif /* not VMS */ +#endif /* not DOS_NT */ } baud_rate = (ospeed < sizeof baud_convert / sizeof baud_convert[0] - ? baud_convert[ospeed] : 9600); + ? baud_convert[ospeed] : 9600); if (baud_rate == 0) baud_rate = 1200; } @@ -275,7 +347,7 @@ set_exclusive_use (fd) #endif /* Ok to do nothing if this feature does not exist */ } - + #ifndef subprocesses wait_without_blocking () @@ -291,7 +363,7 @@ wait_without_blocking () #endif /* not subprocesses */ int wait_debugging; /* Set nonzero to make following function work under dbx - (at least for bsd). */ + (at least for bsd). */ SIGTYPE wait_for_termination_signal () @@ -322,7 +394,7 @@ wait_for_termination (pid) if that causes the problem to go away or get worse. */ sigsetmask (sigmask (SIGCHLD)); if (0 > kill (pid, 0)) - { + { sigsetmask (SIGEMPTYMASK); kill (getpid (), SIGCHLD); break; @@ -337,7 +409,7 @@ wait_for_termination (pid) break; wait (0); #else /* neither BSD nor UNIPLUS: random sysV */ -#ifdef POSIX_SIGNALS /* would this work for LINUX as well? */ +#ifdef POSIX_SIGNALS /* would this work for LINUX as well? */ sigblock (sigmask (SIGCHLD)); if (0 > kill (pid, 0)) { @@ -355,12 +427,17 @@ wait_for_termination (pid) } sigpause (SIGCHLD); #else /* not HAVE_SYSV_SIGPAUSE */ +#ifdef WINDOWSNT + wait (0); + break; +#else /* not WINDOWSNT */ if (0 > kill (pid, 0)) break; /* Using sleep instead of pause avoids timing error. If the inferior dies just before the sleep, we lose just one second. */ sleep (1); +#endif /* not WINDOWSNT */ #endif /* not HAVE_SYSV_SIGPAUSE */ #endif /* not POSIX_SIGNALS */ #endif /* not UNIPLUS */ @@ -408,7 +485,7 @@ flush_pending_output (channel) #endif #endif } - + #ifndef VMS /* Set up the terminal at the other end of a pseudo-terminal that we will be controlling an inferior through. @@ -418,6 +495,7 @@ flush_pending_output (channel) child_setup_tty (out) int out; { +#ifndef DOS_NT struct emacs_tty s; EMACS_GET_TTY (out, &s); @@ -425,14 +503,19 @@ child_setup_tty (out) #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS) s.main.c_oflag |= OPOST; /* Enable output postprocessing */ s.main.c_oflag &= ~ONLCR; /* Disable map of NL to CR-NL on output */ +#ifdef NLDLY s.main.c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); /* No output delays */ +#endif s.main.c_lflag &= ~ECHO; /* Disable echo */ s.main.c_lflag |= ISIG; /* Enable signals */ - s.main.c_iflag &= ~IUCLC; /* Disable map of upper case to lower on - input */ - s.main.c_oflag &= ~OLCUC; /* Disable map of lower case to upper on - output */ +#ifdef IUCLC + s.main.c_iflag &= ~IUCLC; /* Disable downcasing on input. */ +#endif +#ifdef OLCUC + s.main.c_oflag &= ~OLCUC; /* Disable upcasing on output. */ +#endif + s.main.c_cflag = (s.main.c_cflag & ~CSIZE) | CS8; /* Don't strip 8th bit */ #if 0 /* Said to be unnecessary: */ s.main.c_cc[VMIN] = 1; /* minimum number of characters to accept */ @@ -441,8 +524,8 @@ child_setup_tty (out) s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */ s.main.c_cc[VEOF] = 04; /* insure that EOF is Control-D */ - s.main.c_cc[VERASE] = 0377; /* disable erase processing */ - s.main.c_cc[VKILL] = 0377; /* disable kill processing */ + s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */ + s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */ #ifdef HPUX s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */ @@ -481,8 +564,10 @@ child_setup_tty (out) s.main.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE | CBREAK | TANDEM); + s.main.sg_flags |= LPASS8; s.main.sg_erase = 0377; s.main.sg_kill = 0377; + s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */ #endif /* not HAVE_TERMIO */ @@ -498,18 +583,12 @@ child_setup_tty (out) ioctl (out, FIOASYNC, &zero); } #endif /* RTU */ +#endif /* not DOS_NT */ } #endif /* not VMS */ #endif /* subprocesses */ - -/*ARGSUSED*/ -setpgrp_of_tty (pid) - int pid; -{ - EMACS_SET_TTY_PGRP (input_fd, &pid); -} - + /* Record a signal code and the handler for it. */ struct save_signal { @@ -562,14 +641,10 @@ sys_suspend () } return -1; #else -#ifdef SIGTSTP +#if defined(SIGTSTP) && !defined(MSDOS) { -#ifdef USG - int pgrp = getpgrp (); -#else - int pgrp = getpgrp (0); -#endif + int pgrp = EMACS_GETPGRP (0); EMACS_KILLPG (pgrp, SIGTSTP); } @@ -583,8 +658,27 @@ sys_suspend () /* On a system where suspending is not implemented, instead fork a subshell and let it talk directly to the terminal while we wait. */ - int pid = fork (); + sys_subshell (); + +#endif /* no USG_JOBCTRL */ +#endif /* no SIGTSTP */ +#endif /* not VMS */ +} + +/* Fork a subshell. */ + +sys_subshell () +{ +#ifndef VMS +#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */ + int st; + char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */ +#endif + int pid; struct save_signal saved_handlers[5]; + Lisp_Object dir; + unsigned char *str = 0; + int len; saved_handlers[0].code = SIGINT; saved_handlers[1].code = SIGQUIT; @@ -596,66 +690,88 @@ sys_suspend () saved_handlers[3].code = 0; #endif + /* Mentioning current_buffer->buffer would mean including buffer.h, + which somehow wedges the hp compiler. So instead... */ + + dir = intern ("default-directory"); + if (NILP (Fboundp (dir))) + goto xyzzy; + dir = Fsymbol_value (dir); + if (!STRINGP (dir)) + goto xyzzy; + + dir = expand_and_dir_to_file (Funhandled_file_name_directory (dir), Qnil); + str = (unsigned char *) alloca (XSTRING (dir)->size + 2); + len = XSTRING (dir)->size; + bcopy (XSTRING (dir)->data, str, len); + if (str[len - 1] != '/') str[len++] = '/'; + str[len] = 0; + xyzzy: + +#ifdef WINDOWSNT + pid = -1; +#else /* not WINDOWSNT */ + pid = vfork (); + if (pid == -1) error ("Can't spawn subshell"); if (pid == 0) +#endif /* not WINDOWSNT */ { char *sh; +#ifdef MSDOS /* MW, Aug 1993 */ + getwd (oldwd); +#endif sh = (char *) egetenv ("SHELL"); if (sh == 0) sh = "sh"; + /* Use our buffer's default directory for the subshell. */ - { - Lisp_Object dir; - unsigned char *str; - int len; - - /* mentioning current_buffer->buffer would mean including buffer.h, - which somehow wedges the hp compiler. So instead... */ - - dir = intern ("default-directory"); - /* Can't use NULL */ - if (XFASTINT (Fboundp (dir)) == XFASTINT (Qnil)) - goto xyzzy; - dir = Fsymbol_value (dir); - if (XTYPE (dir) != Lisp_String) - goto xyzzy; - - str = (unsigned char *) alloca (XSTRING (dir)->size + 2); - len = XSTRING (dir)->size; - bcopy (XSTRING (dir)->data, str, len); - if (str[len - 1] != '/') str[len++] = '/'; - str[len] = 0; + if (str) chdir (str); - } - xyzzy: + #ifdef subprocesses close_process_descs (); /* Close Emacs's pipes/ptys */ #endif -#ifdef PRIO_PROCESS +#ifdef SET_EMACS_PRIORITY { extern int emacs_priority; - if (emacs_priority) + if (emacs_priority < 0) nice (-emacs_priority); } #endif +#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */ + st = system (sh); + chdir (oldwd); + if (st) + report_file_error ("Can't execute subshell", Fcons (build_string (sh), Qnil)); +#else /* not MSDOS */ +#ifdef WINDOWSNT + restore_console (); + + /* Waits for process completion */ + pid = _spawnlp (_P_WAIT, sh, sh, NULL); + if (pid == -1) + write (1, "Can't execute subshell", 22); + + take_console (); +#else /* not WINDOWSNT */ execlp (sh, sh, 0); write (1, "Can't execute subshell", 22); _exit (1); +#endif /* not WINDOWSNT */ +#endif /* not MSDOS */ } save_signal_handlers (saved_handlers); synch_process_alive = 1; wait_for_termination (pid); restore_signal_handlers (saved_handlers); - -#endif /* no USG_JOBCTRL */ -#endif /* no SIGTSTP */ -#endif /* not VMS */ +#endif /* !VMS */ } save_signal_handlers (saved_handlers) @@ -683,12 +799,14 @@ restore_signal_handlers (saved_handlers) int old_fcntl_flags; -init_sigio () +init_sigio (fd) + int fd; { #ifdef FASYNC - old_fcntl_flags = fcntl (0, F_GETFL, 0) & ~FASYNC; + old_fcntl_flags = fcntl (fd, F_GETFL, 0) & ~FASYNC; + fcntl (fd, F_SETFL, old_fcntl_flags | FASYNC); #endif - request_sigio (); + interrupts_deferred = 0; } reset_sigio () @@ -700,20 +818,26 @@ reset_sigio () request_sigio () { + if (read_socket_hook) + return; + #ifdef SIGWINCH sigunblock (sigmask (SIGWINCH)); #endif - fcntl (0, F_SETFL, old_fcntl_flags | FASYNC); + fcntl (input_fd, F_SETFL, old_fcntl_flags | FASYNC); interrupts_deferred = 0; } unrequest_sigio () { + if (read_socket_hook) + return; + #ifdef SIGWINCH sigblock (sigmask (SIGWINCH)); #endif - fcntl (0, F_SETFL, old_fcntl_flags); + fcntl (input_fd, F_SETFL, old_fcntl_flags); interrupts_deferred = 1; } @@ -723,7 +847,11 @@ unrequest_sigio () request_sigio () { int on = 1; - ioctl (0, FIOASYNC, &on); + + if (read_socket_hook) + return; + + ioctl (input_fd, FIOASYNC, &on); interrupts_deferred = 0; } @@ -731,29 +859,71 @@ unrequest_sigio () { int off = 0; - ioctl (0, FIOASYNC, &off); + if (read_socket_hook) + return; + + ioctl (input_fd, FIOASYNC, &off); interrupts_deferred = 1; } #else /* not FASYNC, not STRIDE */ +#ifdef _CX_UX + +#include + request_sigio () { + int on = 1; + sigset_t st; + + if (read_socket_hook) + return; + + sigemptyset(&st); + sigaddset(&st, SIGIO); + ioctl (input_fd, FIOASYNC, &on); + interrupts_deferred = 0; + sigprocmask(SIG_UNBLOCK, &st, (sigset_t *)0); +} + +unrequest_sigio () +{ + int off = 0; + + if (read_socket_hook) + return; + + ioctl (input_fd, FIOASYNC, &off); + interrupts_deferred = 1; +} + +#else /* ! _CX_UX */ + +request_sigio () +{ + if (read_socket_hook) + return; + croak ("request_sigio"); } unrequest_sigio () { + if (read_socket_hook) + return; + croak ("unrequest_sigio"); } +#endif /* _CX_UX */ #endif /* STRIDE */ #endif /* FASYNC */ #endif /* F_SETFL */ /* Saving and restoring the process group of Emacs's terminal. */ -#ifdef BSD +#ifdef BSD_PGRPS /* The process group of which Emacs was a member when it initially started. @@ -785,7 +955,7 @@ narrow_foreground_group () setpgrp (0, inherited_pgroup); if (inherited_pgroup != me) - EMACS_SET_TTY_PGRP (0, &me); + EMACS_SET_TTY_PGRP (input_fd, &me); setpgrp (0, me); } @@ -793,11 +963,11 @@ narrow_foreground_group () widen_foreground_group () { if (inherited_pgroup != getpid ()) - EMACS_SET_TTY_PGRP (0, &inherited_pgroup); + EMACS_SET_TTY_PGRP (input_fd, &inherited_pgroup); setpgrp (0, inherited_pgroup); } -#endif +#endif /* BSD_PGRPS */ /* Getting and setting emacs_tty structures. */ @@ -830,10 +1000,11 @@ emacs_get_tty (fd, settings) return -1; #else +#ifndef DOS_NT /* I give up - I hope you have the BSD ioctls. */ if (ioctl (fd, TIOCGETP, &settings->main) < 0) return -1; - +#endif /* not DOS_NT */ #endif #endif #endif @@ -921,9 +1092,11 @@ emacs_set_tty (fd, settings, waitp) return -1; #else +#ifndef DOS_NT /* I give up - I hope you have the BSD ioctls. */ if (ioctl (fd, (waitp) ? TIOCSETP : TIOCSETN, &settings->main) < 0) return -1; +#endif /* not DOS_NT */ #endif #endif @@ -1027,18 +1200,26 @@ init_sys_modes () #endif #endif /* not VMS */ -#ifdef BSD +#ifdef BSD_PGRPS if (! read_socket_hook && EQ (Vwindow_system, Qnil)) narrow_foreground_group (); #endif - EMACS_GET_TTY (input_fd, &old_tty); - +#ifdef HAVE_X_WINDOWS + /* Emacs' window system on MSDOG uses the `internal terminal' and therefore + needs the initialization code below. */ if (!read_socket_hook && EQ (Vwindow_system, Qnil)) +#endif { + EMACS_GET_TTY (input_fd, &old_tty); + tty = old_tty; #if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS) +#ifdef DGUX + /* This allows meta to be sent on 8th bit. */ + tty.main.c_iflag &= ~INPCK; /* don't check input for parity */ +#endif tty.main.c_iflag |= (IGNBRK); /* Ignore break condition */ tty.main.c_iflag &= ~ICRNL; /* Disable map of CR to NL on input */ #ifdef ISTRIP @@ -1047,7 +1228,7 @@ init_sys_modes () tty.main.c_lflag &= ~ECHO; /* Disable echo */ tty.main.c_lflag &= ~ICANON; /* Disable erase/kill processing */ #ifdef IEXTEN - tty.main.c_iflag &= ~IEXTEN; /* Disable other editing characters. */ + tty.main.c_lflag &= ~IEXTEN; /* Disable other editing characters. */ #endif tty.main.c_lflag |= ISIG; /* Enable signals */ if (flow_control) @@ -1102,10 +1283,21 @@ init_sys_modes () #ifdef VDISCARD tty.main.c_cc[VDISCARD] = CDISABLE; #endif /* VDISCARD */ +#ifdef VSTART + tty.main.c_cc[VSTART] = CDISABLE; +#endif /* VSTART */ +#ifdef VSTOP + tty.main.c_cc[VSTOP] = CDISABLE; +#endif /* VSTOP */ #endif /* mips or HAVE_TCATTR */ +#ifdef SET_LINE_DISCIPLINE + /* Need to explicitely request TERMIODISC line discipline or + Ultrix's termios does not work correctly. */ + tty.main.c_line = SET_LINE_DISCIPLINE; +#endif #ifdef AIX #ifndef IBMR2AIX - /* AIX enhanced edit loses NULs, so disable it */ + /* AIX enhanced edit loses NULs, so disable it. */ tty.main.c_line = 0; tty.main.c_iflag &= ~ASCEDIT; #else @@ -1132,10 +1324,12 @@ init_sys_modes () tty.main.tt_char &= ~TT$M_TTSYNC; tty.main.tt2_char |= TT2$M_PASTHRU | TT2$M_XON; #else /* not VMS (BSD, that is) */ +#ifndef DOS_NT tty.main.sg_flags &= ~(ECHO | CRMOD | XTABS); if (meta_key) tty.main.sg_flags |= ANYP; tty.main.sg_flags |= interrupt_input ? RAW : CBREAK; +#endif /* not DOS_NT */ #endif /* not VMS (BSD, that is) */ #endif /* not HAVE_TERMIO */ @@ -1156,15 +1350,6 @@ init_sys_modes () tty.tchars.t_stopc = '\023'; } -/* LPASS8 is new in 4.3, and makes cbreak mode provide all 8 bits. */ -#ifndef LPASS8 -#define LPASS8 0 -#endif - -#ifdef BSD4_1 -#define LNOFLSH 0100000 -#endif - tty.lmode = LDECCTQ | LLITOUT | LPASS8 | LNOFLSH | old_tty.lmode; #ifdef ultrix /* Under Ultrix 4.2a, leaving this out doesn't seem to hurt @@ -1182,6 +1367,11 @@ init_sys_modes () #ifdef HAVE_LTCHARS tty.ltchars = new_ltchars; #endif /* HAVE_LTCHARS */ +#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida, MW Aug 1993 */ + if (!term_initted) + internal_terminal_init (); + dos_ttraw (); +#endif EMACS_SET_TTY (input_fd, &tty, 0); @@ -1189,15 +1379,19 @@ init_sys_modes () we have an unlocked terminal at the start. */ #ifdef TCXONC - if (!flow_control) ioctl (0, TCXONC, 1); + if (!flow_control) ioctl (input_fd, TCXONC, 1); #endif #ifndef APOLLO #ifdef TIOCSTART - if (!flow_control) ioctl (0, TIOCSTART, 0); + if (!flow_control) ioctl (input_fd, TIOCSTART, 0); #endif #endif -#ifdef AIX +#if defined (HAVE_TERMIOS) || defined (HPUX9) + if (!flow_control) tcflow (input_fd, TCOON); +#endif + +#ifdef AIXHFT hft_init (); #ifdef IBMR2AIX { @@ -1209,7 +1403,7 @@ init_sys_modes () write (1, "\033[20l", 5); } #endif -#endif +#endif /* AIXHFT */ #ifdef VMS /* Appears to do nothing when in PASTHRU mode. @@ -1223,11 +1417,12 @@ init_sys_modes () #ifdef F_SETFL #ifndef F_SETOWN_BUG #ifdef F_GETOWN /* F_SETFL does not imply existence of F_GETOWN */ - if (interrupt_input) + if (interrupt_input + && ! read_socket_hook && EQ (Vwindow_system, Qnil)) { - old_fcntl_owner = fcntl (0, F_GETOWN, 0); - fcntl (0, F_SETOWN, getpid ()); - init_sigio (); + old_fcntl_owner = fcntl (input_fd, F_GETOWN, 0); + fcntl (input_fd, F_SETOWN, getpid ()); + init_sigio (input_fd); } #endif /* F_GETOWN */ #endif /* F_SETOWN_BUG */ @@ -1235,7 +1430,7 @@ init_sys_modes () #ifdef BSD4_1 if (interrupt_input) - init_sigio (); + init_sigio (input_fd); #endif #ifdef VMS /* VMS sometimes has this symbol but lacks setvbuf. */ @@ -1249,7 +1444,9 @@ init_sys_modes () #else setbuf (stdout, _sobuf); #endif - set_terminal_modes (); + if (! read_socket_hook && EQ (Vwindow_system, Qnil)) + set_terminal_modes (); + if (term_initted && no_redraw_on_reenter) { if (display_completed) @@ -1277,10 +1474,10 @@ tabs_safe_p () EMACS_GET_TTY (input_fd, &tty); return EMACS_TTY_TABS_OK (&tty); } - + /* Get terminal size from system. - Store number of lines into *heightp and width into *widthp. - If zero or a negative number is stored, the value is not valid. */ + Store number of lines into *HEIGHTP and width into *WIDTHP. + We store 0 if there's no valid information. */ get_frame_size (widthp, heightp) int *widthp, *heightp; @@ -1323,16 +1520,57 @@ get_frame_size (widthp, heightp) *widthp = tty.scr_wid; *heightp = tty.scr_len; +#else +#ifdef MSDOS + *widthp = ScreenCols (); + *heightp = ScreenRows (); #else /* system doesn't know size */ - *widthp = 0; *heightp = 0; +#endif #endif /* not VMS */ #endif /* not SunOS-style */ #endif /* not BSD-style */ } +/* Set the logical window size associated with descriptor FD + to HEIGHT and WIDTH. This is used mainly with ptys. */ + +int +set_window_size (fd, height, width) + int fd, height, width; +{ +#ifdef TIOCSWINSZ + + /* BSD-style. */ + struct winsize size; + size.ws_row = height; + size.ws_col = width; + + if (ioctl (fd, TIOCSWINSZ, &size) == -1) + return 0; /* error */ + else + return 1; + +#else +#ifdef TIOCSSIZE + + /* SunOS - style. */ + struct ttysize size; + size.ts_lines = height; + size.ts_cols = width; + + if (ioctl (fd, TIOCGSIZE, &size) == -1) + return 0; + else + return 1; +#else + return -1; +#endif /* not SunOS-style */ +#endif /* not BSD-style */ +} + /* Prepare the terminal for exiting Emacs; move the cursor to the bottom of the frame, turn off interrupt-driven I/O, etc. */ @@ -1345,13 +1583,26 @@ reset_sys_modes () } if (!term_initted) return; +#ifdef HAVE_X_WINDOWS + /* Emacs' window system on MSDOG uses the `internal terminal' and therefore + needs the clean-up code below. */ if (read_socket_hook || !EQ (Vwindow_system, Qnil)) return; +#endif cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0); +#ifdef MSDOS + if (!EQ (Vwindow_system, Qnil)) + { + /* Change to grey on white. */ + putchar ('\e'); + putchar ('A'); + putchar (7); + } +#endif clear_end_of_line (FRAME_WIDTH (selected_frame)); /* clear_end_of_line may move the cursor */ cursor_to (FRAME_HEIGHT (selected_frame) - 1, 0); -#ifdef IBMR2AIX +#if defined (IBMR2AIX) && defined (AIXHFT) { /* HFT devices normally use ^J as a LF/CR. We forced it to do the LF only. Now, we need to reset it. */ @@ -1377,10 +1628,13 @@ reset_sys_modes () if (interrupt_input) { reset_sigio (); - fcntl (0, F_SETOWN, old_fcntl_owner); + fcntl (input_fd, F_SETOWN, old_fcntl_owner); } #endif /* F_SETOWN */ #endif /* F_SETOWN_BUG */ +#ifdef O_NDELAY + fcntl (input_fd, F_SETFL, fcntl (input_fd, F_GETFL, 0) & ~O_NDELAY); +#endif #endif /* F_SETFL */ #ifdef BSD4_1 if (interrupt_input) @@ -1390,11 +1644,22 @@ reset_sys_modes () while (EMACS_SET_TTY (input_fd, &old_tty, 0) < 0 && errno == EINTR) ; -#ifdef AIX +#ifdef MSDOS /* Demacs 1.1.2 91/10/20 Manabu Higashida */ + dos_ttcooked (); +#endif + +#ifdef SET_LINE_DISCIPLINE + /* Ultrix's termios *ignores* any line discipline except TERMIODISC. + A different old line discipline is therefore not restored, yet. + Restore the old line discipline by hand. */ + ioctl (0, TIOCSETD, &old_tty.main.c_line); +#endif + +#ifdef AIXHFT hft_reset (); #endif -#ifdef BSD +#ifdef BSD_PGRPS widen_foreground_group (); #endif } @@ -1531,12 +1796,8 @@ kbd_input_ast () { struct input_event e; e.kind = ascii_keystroke; - XSET (e.code, Lisp_Int, c); -#ifdef MULTI_FRAME - XSET(e.frame_or_window, Lisp_Frame, selected_frame); -#else - e.frame_or_window = Qnil; -#endif + XSETINT (e.code, c); + XSETFRAME (e.frame_or_window, selected_frame); kbd_buffer_store_event (&e); } if (input_available_clear_time) @@ -1578,6 +1839,7 @@ wait_for_kbd_input () if (dsp) { update_mode_lines++; + prepare_menu_bars (); redisplay_preserve_echo_area (); } } @@ -1663,7 +1925,8 @@ sys_sleep (timeval) SYS$WAITFR (timer_ef); /* Wait for timer expiry only */ } -init_sigio () +init_sigio (fd) + int fd; { request_sigio (); } @@ -1706,7 +1969,7 @@ unrequest_sigio () * */ -#ifndef CANNOT_UNEXEC +#ifndef HAVE_TEXT_START char * start_of_text () { @@ -1722,7 +1985,7 @@ start_of_text () #endif /* GOULD */ #endif /* TEXT_START */ } -#endif /* not CANNOT_UNEXEC */ +#endif /* not HAVE_TEXT_START */ /* * Return the address of the start of the data segment prior to @@ -1811,64 +2074,63 @@ end_of_data () #endif /* not CANNOT_DUMP */ -/* Get_system_name returns as its value - a string for the Lisp function system-name to return. */ +/* init_system_name sets up the string for the Lisp function + system-name to return. */ #ifdef BSD4_1 #include #endif -/* Can't have this within the function since `static' is #defined to - nothing for some USG systems. */ -#ifdef USG -#ifdef HAVE_GETHOSTNAME -static char get_system_name_name[256]; -#else /* not HAVE_GETHOSTNAME */ -static struct utsname get_system_name_name; -#endif /* not HAVE_GETHOSTNAME */ -#endif /* USG */ +extern Lisp_Object Vsystem_name; #ifndef BSD4_1 -#ifndef USG #ifndef VMS #ifdef HAVE_SOCKETS #include #include #endif /* HAVE_SOCKETS */ #endif /* not VMS */ -#endif /* not USG */ #endif /* not BSD4_1 */ -char * -get_system_name () +void +init_system_name () { -#ifdef USG -#ifdef HAVE_GETHOSTNAME - gethostname (get_system_name_name, sizeof (get_system_name_name)); - return get_system_name_name; -#else /* not HAVE_GETHOSTNAME */ - uname (&get_system_name_name); - return (get_system_name_name.nodename); -#endif /* not HAVE_GETHOSTNAME */ -#else /* Not USG */ #ifdef BSD4_1 - return sysname; -#else /* not USG, not 4.1 */ - static char system_name_saved[32]; + Vsystem_name = build_string (sysname); +#else #ifdef VMS - char *sp; + char *sp, *end; if ((sp = egetenv ("SYS$NODE")) == 0) - sp = "vax-vms"; + Vsystem_name = build_string ("vax-vms"); + else if ((end = index (sp, ':')) == 0) + Vsystem_name = build_string (sp); else + Vsystem_name = make_string (sp, end - sp); +#else +#ifndef HAVE_GETHOSTNAME + struct utsname uts; + uname (&uts); + Vsystem_name = build_string (uts.nodename); +#else /* HAVE_GETHOSTNAME */ + int hostname_size = 256; + char *hostname = (char *) alloca (hostname_size); + + /* Try to get the host name; if the buffer is too short, try + again. Apparently, the only indication gethostname gives of + whether the buffer was large enough is the presence or absence + of a '\0' in the string. Eech. */ + for (;;) { - char *end; + gethostname (hostname, hostname_size - 1); + hostname[hostname_size - 1] = '\0'; + + /* Was the buffer large enough for the '\0'? */ + if (strlen (hostname) < hostname_size - 1) + break; - if ((end = index (sp, ':')) != 0) - *end = '\0'; + hostname_size <<= 1; + hostname = (char *) alloca (hostname_size); } - strcpy (system_name_saved, sp); -#else /* not VMS */ - gethostname (system_name_saved, sizeof (system_name_saved)); #ifdef HAVE_SOCKETS /* Turn the hostname into the official, fully-qualified hostname. Don't do this if we're going to dump; this can confuse system @@ -1878,35 +2140,61 @@ get_system_name () #endif /* not CANNOT_DUMP */ { struct hostent *hp; - hp = gethostbyname (system_name_saved); - if (hp && strlen (hp->h_name) < sizeof(system_name_saved)) - strcpy (system_name_saved, hp->h_name); + int count; + for (count = 0; count < 10; count++) + { +#ifdef TRY_AGAIN + h_errno = 0; +#endif + hp = gethostbyname (hostname); +#ifdef TRY_AGAIN + if (! (hp == 0 && h_errno == TRY_AGAIN)) +#endif + break; + Fsleep_for (make_number (1), Qnil); + } + if (hp) + { + char *fqdn = hp->h_name; + char *p; + + if (!index (fqdn, '.')) + { + /* We still don't have a fully qualified domain name. + Try to find one in the list of alternate names */ + char **alias = hp->h_aliases; + while (*alias && !index (*alias, '.')) + alias++; + if (*alias) + fqdn = *alias; + } + hostname = fqdn; +#if 0 + /* Convert the host name to lower case. */ + /* Using ctype.h here would introduce a possible locale + dependence that is probably wrong for hostnames. */ + p = hostname; + while (*p) + { + if (*p >= 'A' && *p <= 'Z') + *p += 'a' - 'A'; + p++; + } +#endif + } } #endif /* HAVE_SOCKETS */ -#endif /* not VMS */ - return system_name_saved; -#endif /* not USG, not 4.1 */ -#endif /* not USG */ -} - -#ifdef VMS -#ifndef HAVE_GETHOSTNAME -void gethostname(buf, len) - char *buf; - int len; -{ - char *s; - s = getenv ("SYS$NODE"); - if (s == NULL) - buf[0] = '\0'; - else { - strncpy (buf, s, len - 2); - buf[len - 1] = '\0'; - } /* else */ -} /* static void gethostname */ -#endif /* ! HAVE_GETHOSTNAME */ + Vsystem_name = build_string (hostname); +#endif /* HAVE_GETHOSTNAME */ #endif /* VMS */ - +#endif /* BSD4_1 */ + { + unsigned char *p; + for (p = XSTRING (Vsystem_name)->data; *p; p++) + if (*p == ' ' || *p == '\t') + *p = '-'; + } +} #ifndef VMS #ifndef HAVE_SELECT @@ -1946,6 +2234,7 @@ select_alarm () longjmp (read_alarm_throw, 1); } +#ifndef WINDOWSNT /* Only rfds are checked. */ int select (nfds, rfds, wfds, efds, timeout) @@ -2007,6 +2296,9 @@ select (nfds, rfds, wfds, efds, timeout) #ifdef FIONREAD status = ioctl (fd, FIONREAD, &avail); #else /* no FIONREAD */ +#ifdef MSDOS + abort (); /* I don't think we need it. */ +#else /* not MSDOS */ /* Hoping it will return -1 if nothing available or 0 if all 0 chars requested are read. */ if (proc_buffered_char[fd] >= 0) @@ -2017,6 +2309,7 @@ select (nfds, rfds, wfds, efds, timeout) if (avail > 0) proc_buffered_char[fd] = buf; } +#endif /* not MSDOS */ #endif /* no FIONREAD */ } if (status >= 0 && avail > 0) @@ -2037,6 +2330,10 @@ select (nfds, rfds, wfds, efds, timeout) while (select_alarmed == 0 && *local_timeout != 0 && process_tick == update_tick) { +#ifdef MSDOS + sleep_or_kbd_hit (SELECT_PAUSE, (orfds & 1) != 0); + select_alarm (); +#else /* not MSDOS */ /* If we are interested in terminal input, wait by reading the terminal. That makes instant wakeup for terminal input at least. */ @@ -2048,6 +2345,7 @@ select (nfds, rfds, wfds, efds, timeout) } else pause (); +#endif /* not MSDOS */ } (*local_timeout) -= SELECT_PAUSE; /* Reset the old alarm if there was one */ @@ -2067,6 +2365,7 @@ select (nfds, rfds, wfds, efds, timeout) } return ravail; } +#endif /* not WINDOWSNT */ /* Read keyboard input into the standard buffer, waiting for at least one character. */ @@ -2080,34 +2379,60 @@ select (nfds, rfds, wfds, efds, timeout) read_input_waiting () { - char buf[256 * BUFFER_SIZE_FACTOR]; struct input_event e; int nread, i; extern int quit_char; if (read_socket_hook) { + struct input_event buf[256]; + read_alarm_should_throw = 0; if (! setjmp (read_alarm_throw)) - nread = (*read_socket_hook) (0, buf, 256 * BUFFER_SIZE_FACTOR, 1, 0); + nread = (*read_socket_hook) (0, buf, 256, 1, 0); else nread = -1; + + /* Scan the chars for C-g and store them in kbd_buffer. */ + for (i = 0; i < nread; i++) + { + kbd_buffer_store_event (&buf[i]); + /* Don't look at input that follows a C-g too closely. + This reduces lossage due to autorepeat on C-g. */ + if (buf[i].kind == ascii_keystroke + && XINT(buf[i].code) == quit_char) + break; + } } else - nread = read (fileno (stdin), buf, 1); - - /* Scan the chars for C-g and store them in kbd_buffer. */ - e.kind = ascii_keystroke; - e.frame_or_window = selected_frame; - e.modifiers = 0; - for (i = 0; i < nread; i++) { - XSET (e.code, Lisp_Int, buf[i]); - kbd_buffer_store_event (&e); - /* Don't look at input that follows a C-g too closely. - This reduces lossage due to autorepeat on C-g. */ - if (buf[i] == quit_char) - break; + char buf[3]; + nread = read (fileno (stdin), buf, 1); + + /* Scan the chars for C-g and store them in kbd_buffer. */ + e.kind = ascii_keystroke; + XSETFRAME (e.frame_or_window, selected_frame); + e.modifiers = 0; + for (i = 0; i < nread; i++) + { + /* Convert chars > 0177 to meta events if desired. + We do this under the same conditions that read_avail_input does. */ + if (read_socket_hook == 0) + { + /* If the user says she has a meta key, then believe her. */ + if (meta_key == 1 && (buf[i] & 0x80)) + e.modifiers = meta_modifier; + if (meta_key != 2) + buf[i] &= ~0x80; + } + + XSETINT (e.code, buf[i]); + kbd_buffer_store_event (&e); + /* Don't look at input that follows a C-g too closely. + This reduces lossage due to autorepeat on C-g. */ + if (buf[i] == quit_char) + break; + } } } @@ -2134,12 +2459,13 @@ sys_open (path, oflag, mode) return open (path, oflag); } -init_sigio () +init_sigio (fd) + int fd; { if (noninteractive) return; lmode = LINTRUP | lmode; - ioctl (0, TIOCLSET, &lmode); + ioctl (fd, TIOCLSET, &lmode); } reset_sigio () @@ -2229,7 +2555,14 @@ sys_signal (int signal_number, signal_handler_t action) #else sigemptyset (&new_action.sa_mask); new_action.sa_handler = action; +#ifdef SA_RESTART + /* Emacs mostly works better with restartable system services. If this + * flag exists, we probably want to turn it on here. + */ + new_action.sa_flags = SA_RESTART; +#else new_action.sa_flags = 0; +#endif sigaction (signal_number, &new_action, &old_action); return (old_action.sa_handler); #endif /* DGUX */ @@ -2289,6 +2622,8 @@ sys_sigsetmask (sigset_t new_mask) #ifndef BSTRING +#ifndef bzero + void bzero (b, length) register char *b; @@ -2311,6 +2646,9 @@ bzero (b, length) #endif /* not VMS */ } +#endif /* no bzero */ + +#ifndef bcopy /* Saying `void' requires a declaration, above, where bcopy is used and that declaration causes pain for systems where bcopy is a macro. */ bcopy (b1, b2, length) @@ -2334,7 +2672,9 @@ bcopy (b1, b2, length) *b2++ = *b1++; #endif /* not VMS */ } +#endif /* no bcopy */ +#ifndef bcmp int bcmp (b1, b2, length) /* This could be a macro! */ register char *b1; @@ -2354,10 +2694,13 @@ bcmp (b1, b2, length) /* This could be a macro! */ return 0; #endif /* not VMS */ } +#endif /* no bcmp */ + #endif /* not BSTRING */ #ifndef HAVE_RANDOM -#ifdef USG +#ifndef random + /* * The BSD random returns numbers in the range of * 0 to 2e31 - 1. The USG rand returns numbers in the @@ -2368,32 +2711,33 @@ bcmp (b1, b2, length) /* This could be a macro! */ long random () { - /* Arrange to return a range centered on zero. */ - return (rand () << 15) + rand () - (1 << 29); +#ifdef HAVE_LRAND48 + return lrand48 (); +#else +/* The BSD rand returns numbers in the range of 0 to 2e31 - 1, + with unusable least significant bits. The USG rand returns + numbers in the range of 0 to 2e15 - 1, all usable. Let us + build a usable 30 bit number from either. */ +#ifdef USG + return (rand () << 15) + rand (); +#else + return (rand () & 0x3fff8000) + (rand () >> 16); +#endif +#endif } srandom (arg) int arg; { +#ifdef HAVE_LRAND48 + srand48 (arg); +#else srand (arg); +#endif } -#endif /* USG */ - -#ifdef BSD4_1 -long random () -{ - /* Arrange to return a range centered on zero. */ - return (rand () << 15) + rand () - (1 << 29); -} - -srandom (arg) - int arg; -{ - srand (arg); -} -#endif /* BSD4_1 */ -#endif +#endif /* no random */ +#endif /* not HAVE_RANDOM */ #ifdef WRONG_NAME_INSQUE @@ -2510,6 +2854,22 @@ char *sys_errlist[] = #endif /* SHAREABLE_LIB_BUG */ #endif /* LINK_CRTL_SHARE */ #endif /* VMS */ + +#ifndef HAVE_STRERROR +#ifndef WINDOWSNT +char * +strerror (errnum) + int errnum; +{ + extern char *sys_errlist[]; + extern int sys_nerr; + + if (errnum >= 0 && errnum < sys_nerr) + return sys_errlist[errnum]; + return (char *) "Unknown error"; +} +#endif /* not WINDOWSNT */ +#endif /* ! HAVE_STRERROR */ #ifdef INTERRUPTIBLE_OPEN @@ -2563,26 +2923,42 @@ sys_write (fildes, buf, nbyte) char *buf; unsigned int nbyte; { - register int rtnval; + register int rtnval, bytes_written; - while ((rtnval = write (fildes, buf, nbyte)) == -1 - && (errno == EINTR)); - return (rtnval); + bytes_written = 0; + + while (nbyte > 0) + { + rtnval = write (fildes, buf, nbyte); + + if (rtnval == -1) + { + if (errno == EINTR) + continue; + else + return (bytes_written ? bytes_written : -1); + } + + buf += rtnval; + nbyte -= rtnval; + bytes_written += rtnval; + } + return (bytes_written); } #endif /* INTERRUPTIBLE_IO */ #ifndef HAVE_VFORK - +#ifndef WINDOWSNT /* - * Substitute fork for vfork on USG flavors. + * Substitute fork for vfork on USG flavors. */ vfork () { return (fork ()); } - +#endif /* not WINDOWSNT */ #endif /* not HAVE_VFORK */ #ifdef USG @@ -2659,6 +3035,28 @@ char *sys_siglist[NSIG + 1] = "user defined signal 2", /* 17 SIGUSR2 */ "death of a child", /* 18 SIGCLD */ "power-fail restart", /* 19 SIGPWR */ +#ifdef sun + "window size change", /* 20 SIGWINCH */ + "urgent socket condition", /* 21 SIGURG */ + "pollable event occured", /* 22 SIGPOLL */ + "stop (cannot be caught or ignored)", /* 23 SIGSTOP */ + "user stop requested from tty", /* 24 SIGTSTP */ + "stopped process has been continued", /* 25 SIGCONT */ + "background tty read attempted", /* 26 SIGTTIN */ + "background tty write attempted", /* 27 SIGTTOU */ + "virtual timer expired", /* 28 SIGVTALRM */ + "profiling timer expired", /* 29 SIGPROF */ + "exceeded cpu limit", /* 30 SIGXCPU */ + "exceeded file size limit", /* 31 SIGXFSZ */ + "process's lwps are blocked", /* 32 SIGWAITING */ + "special signal used by thread library", /* 33 SIGLWP */ +#ifdef SIGFREEZE + "Special Signal Used By CPR", /* 34 SIGFREEZE */ +#endif +#ifdef SIGTHAW + "Special Signal Used By CPR", /* 35 SIGTHAW */ +#endif +#endif /* sun */ #endif /* not AIX */ 0 }; @@ -2685,6 +3083,8 @@ getwd (pathname) BLOCK_INPUT; /* getcwd uses malloc */ spath = npath = getcwd ((char *) 0, MAXPATHLEN); + if (spath == 0) + return spath; /* On Altos 3068, getcwd can return @hostname/dir, so discard up to first slash. Should be harmless on other systems. */ while (*npath && *npath != '/') @@ -2721,37 +3121,6 @@ rename (from, to) #endif -#ifdef MISSING_UTIMES - -/* HPUX (among others) sets HAVE_TIMEVAL but does not implement utimes. */ - -utimes () -{ -} -#endif - -#ifdef IRIS_UTIME - -/* The IRIS (3.5) has timevals, but uses sys V utime, and doesn't have the - utimbuf structure defined anywhere but in the man page. */ - -struct utimbuf - { - long actime; - long modtime; - }; - -utimes (name, tvp) - char *name; - struct timeval tvp[]; -{ - struct utimbuf utb; - utb.actime = tvp[0].tv_sec; - utb.modtime = tvp[1].tv_sec; - utime (name, &utb); -} -#endif /* IRIS_UTIME */ - #ifdef HPUX #ifndef HAVE_PERROR @@ -2785,7 +3154,7 @@ dup2 (oldd, newd) #ifdef F_DUPFD fd = fcntl (oldd, F_DUPFD, newd); if (fd != newd) - error ("can't dup2 (%i,%i) : %s", oldd, newd, sys_errlist[errno]); + error ("can't dup2 (%i,%i) : %s", oldd, newd, strerror (errno)); #else fd = dup (old); if (fd == -1) @@ -2923,12 +3292,15 @@ char *sys_siglist[NSIG + 1] = #include -#ifndef HAVE_CLOSEDIR +#if defined(BROKEN_CLOSEDIR) || !defined(HAVE_CLOSEDIR) + int closedir (dirp) register DIR *dirp; /* stream from opendir */ { - sys_close (dirp->dd_fd); + int rtnval; + + rtnval = sys_close (dirp->dd_fd); /* Some systems (like Solaris) allocate the buffer and the DIR all in one block. Why in the world are we freeing this ourselves @@ -2937,8 +3309,10 @@ closedir (dirp) xfree ((char *) dirp->dd_buf); /* directory block defined in */ #endif xfree ((char *) dirp); + + return rtnval; } -#endif /* not HAVE_CLOSEDIR */ +#endif /* BROKEN_CLOSEDIR or not HAVE_CLOSEDIR */ #endif /* SYSV_SYSTEM_DIR */ #ifdef NONSYSTEM_DIR_LIBRARY @@ -3086,6 +3460,24 @@ readdirver (dirp) #endif /* NONSYSTEM_DIR_LIBRARY */ +int +set_file_times (filename, atime, mtime) + char *filename; + EMACS_TIME atime, mtime; +{ +#ifdef HAVE_UTIMES + struct timeval tv[2]; + tv[0] = atime; + tv[1] = mtime; + return utimes (filename, tv); +#else /* not HAVE_UTIMES */ + struct utimbuf utb; + utb.actime = EMACS_SECS (atime); + utb.modtime = EMACS_SECS (mtime); + return utime (filename, &utb); +#endif /* not HAVE_UTIMES */ +} + /* mkdir and rmdir functions, for systems which don't have them. */ #ifndef HAVE_MKDIR @@ -3107,10 +3499,14 @@ readdirver (dirp) /* * Make a directory. */ +#ifdef MKDIR_PROTOTYPE +MKDIR_PROTOTYPE +#else int mkdir (dpath, dmode) char *dpath; int dmode; +#endif { int cpid, status, fd; struct stat statbuf; @@ -3194,17 +3590,17 @@ rmdir (dpath) dup2 (fd, 1); dup2 (fd, 2); } - execl ("/bin/rmdir", "rmdir", dpath, (char *) 0); - _exit (-1); /* Can't exec /bin/mkdir */ - - default: /* Parent process */ wait_for_termination (cpid); + if (synch_process_death != 0 || synch_process_retcode != 0) + return -1; /* /bin/rmdir failed */ + default: /* Parent process */ + while (cpid != wait (&status)); /* Wait for kid to finish */ } - if (synch_process_death != 0 || synch_process_retcode != 0) + if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0) { errno = EIO; /* We don't know why, but */ - return -1; /* /bin/rmdir failed */ + return -1; /* /bin/mkdir failed */ } return 0; @@ -3322,8 +3718,8 @@ sys_access (path, mode) #else /* not VMS4_4 */ #include -#define ACE$M_WRITE 2 -#define ACE$C_KEYID 1 +#define ACE$M_WRITE 2 +#define ACE$C_KEYID 1 static unsigned short memid, grpid; static unsigned int uic; @@ -3356,13 +3752,13 @@ sys_access (filename, type) grpid = uic >> 16; } - if (type != 2) /* not checking write access */ + if (type != 2) /* not checking write access */ return access (filename, type); /* Check write protection. */ -#define CHECKPRIV(bit) (prvmask.bit) -#define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE)) +#define CHECKPRIV(bit) (prvmask.bit) +#define WRITEABLE(field) (! ((xab.xab$w_pro >> field) & XAB$M_NOWRITE)) /* Find privilege bits */ status = SYS$SETPRV (0, 0, 0, prvmask); @@ -3564,13 +3960,18 @@ char * getwd (pathname) char *pathname; { - char *ptr; + char *ptr, *val; extern char *getcwd (); #define MAXPATHLEN 1024 ptr = xmalloc (MAXPATHLEN); - getcwd (ptr, MAXPATHLEN); + val = getcwd (ptr, MAXPATHLEN); + if (val == 0) + { + xfree (ptr); + return val; + } strcpy (pathname, ptr); xfree (ptr); @@ -4462,7 +4863,7 @@ srandom (seed) } #endif /* VMS */ -#ifdef AIX +#ifdef AIXHFT /* Called from init_sys_modes. */ hft_init () @@ -4554,4 +4955,31 @@ hft_reset () hftctl (0, HFSKBD, &buf); } -#endif /* AIX */ +#endif /* AIXHFT */ + +#ifdef USE_DL_STUBS + +/* These are included on Sunos 4.1 when we do not use shared libraries. + X11 libraries may refer to these functions but (we hope) do not + actually call them. */ + +void * +dlopen () +{ + return 0; +} + +void * +dlsym () +{ + return 0; +} + +int +dlclose () +{ + return -1; +} + +#endif /* USE_DL_STUBS */ +