#ifdef WINDOWSNT
#include <direct.h>
+#ifndef __MINGW32__
/* <process.h> should not conflict with "process.h", as per ANSI definition.
This is not true though with visual c though. The trick below works with
VC4.2b and with VC5.0. It assumes that VC is installed in a kind of
which will conflict with the macro defined in lisp.h
*/
#include <../include/process.h>
+#else
+#include <mingw32/process.h>
+#endif
#endif /* WINDOWSNT */
#include "lisp.h"
-#include <stddef.h>
#include <stdlib.h>
/* ------------------------------- */
}
#endif
-#ifdef O_NONBLOCK /* The POSIX way */
+#ifdef F_SETFL
fcntl (fd, F_SETFL, O_NONBLOCK);
-#elif defined (O_NDELAY)
- fcntl (fd, F_SETFL, O_NDELAY);
-#endif /* O_NONBLOCK */
+#endif
}
#if defined (NO_SUBPROCESSES)
#endif /* NO_SUBPROCESSES */
-void
-wait_for_termination (int pid)
+#ifdef WINDOWSNT
+void wait_for_termination (HANDLE pHandle)
+#else
+void wait_for_termination (int pid)
+#endif
{
/* #### With the new improved SIGCHLD handling stuff, there is much
less danger of race conditions and some of the comments below
Since implementations may add their own error indicators on top,
we ignore it by default. */
+#elif defined (WINDOWSNT)
+ int ret = 0, status = 0;
+ if (pHandle == NULL)
+ {
+ warn_when_safe (Qprocess, Qwarning, "Cannot wait for unknown process to terminate");
+ return;
+ }
+ do
+ {
+ QUIT;
+ ret = WaitForSingleObject(pHandle, 100);
+ }
+ while (ret == WAIT_TIMEOUT);
+ if (ret == WAIT_FAILED)
+ {
+ warn_when_safe (Qprocess, Qwarning, "waiting for process failed");
+ }
+ if (ret == WAIT_ABANDONED)
+ {
+ warn_when_safe (Qprocess, Qwarning,
+ "process to wait for has been abandoned");
+ }
+ if (ret == WAIT_OBJECT_0)
+ {
+ ret = GetExitCodeProcess(pHandle, &status);
+ if (ret)
+ {
+ synch_process_alive = 0;
+ synch_process_retcode = status;
+ }
+ else
+ {
+ /* GetExitCodeProcess() didn't return a valid exit status,
+ nothing to do. APA */
+ warn_when_safe (Qprocess, Qwarning,
+ "failure to obtain process exit value");
+ }
+ }
+ if (pHandle != NULL && !CloseHandle(pHandle))
+ {
+ warn_when_safe (Qprocess, Qwarning,
+ "failure to close unknown process");
+ }
#elif defined (EMACS_BLOCK_SIGNAL) && !defined (BROKEN_WAIT_FOR_SIGNAL) && defined (SIGCHLD)
while (1)
{
Try defining BROKEN_WAIT_FOR_SIGNAL. */
EMACS_WAIT_FOR_SIGNAL (SIGCHLD);
}
-#else /* not HAVE_WAITPID and (not EMACS_BLOCK_SIGNAL or BROKEN_WAIT_FOR_SIGNAL) */
+#else /* not HAVE_WAITPID and not WINDOWSNT and (not EMACS_BLOCK_SIGNAL or BROKEN_WAIT_FOR_SIGNAL) */
/* This approach is kind of cheesy but is guaranteed(?!) to work
for all systems. */
while (1)
child_setup_tty (int out)
{
struct emacs_tty s;
- EMACS_GET_TTY (out, &s);
+ emacs_get_tty (out, &s);
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
assert (isatty(out));
s.main.c_lflag |= ICANON; /* Enable erase/kill and eof processing */
s.main.c_cc[VEOF] = 04; /* ensure that EOF is Control-D */
- s.main.c_cc[VERASE] = CDISABLE; /* disable erase processing */
- s.main.c_cc[VKILL] = CDISABLE; /* disable kill processing */
+ s.main.c_cc[VERASE] = _POSIX_VDISABLE; /* disable erase processing */
+ s.main.c_cc[VKILL] = _POSIX_VDISABLE; /* disable kill processing */
#ifdef HPUX
s.main.c_cflag = (s.main.c_cflag & ~CBAUD) | B9600; /* baud rate sanity */
#else /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
/* TTY `special characters' work better as signals, so disable
character forms */
- s.main.c_cc[VQUIT] = CDISABLE;
- s.main.c_cc[VINTR] = CDISABLE;
- s.main.c_cc[VSUSP] = CDISABLE;
+ s.main.c_cc[VQUIT] = _POSIX_VDISABLE;
+ s.main.c_cc[VINTR] = _POSIX_VDISABLE;
+ s.main.c_cc[VSUSP] = _POSIX_VDISABLE;
s.main.c_lflag &= ~ISIG;
#endif /* no TIOCGPGRP or no TIOCGLTC or no TIOCGETC */
- s.main.c_cc[VEOL] = CDISABLE;
+ s.main.c_cc[VEOL] = _POSIX_VDISABLE;
#if defined (CBAUD)
/* <mdiers> ### This is not portable. ###
POSIX does not specify CBAUD, and 4.4BSD does not have it.
s.lmode = LLITOUT | s.lmode; /* Don't strip 8th bit */
#endif /* not HAVE_TERMIO */
- EMACS_SET_TTY (out, &s, 0);
+ emacs_set_tty (out, &s, 0);
#ifdef RTU
{
}
#ifdef WINDOWSNT
-int
+pid_t
sys_getpid (void)
{
return abs (getpid ());
static void
sys_subshell (void)
{
+#ifdef WINDOWSNT
+ HANDLE pid;
+#else
int pid;
+#endif
struct save_signal saved_handlers[5];
Lisp_Object dir;
unsigned char *str = 0;
xyzzy:
#ifdef WINDOWSNT
- pid = -1;
+ pid = NULL;
#else /* not WINDOWSNT */
pid = fork ();
#ifdef WINDOWSNT
/* Waits for process completion */
pid = _spawnlp (_P_WAIT, sh, sh, NULL);
- if (pid == -1)
+ if (pid == NULL)
write (1, "Can't execute subshell", 22);
#else /* not WINDOWSNT */
else
return (Bufbyte) t.c_cc[VEOF];
#endif
- return t.c_cc[VEOF] == CDISABLE ? ctrl_d : (Bufbyte) t.c_cc[VEOF];
+ return t.c_cc[VEOF] == _POSIX_VDISABLE ? ctrl_d : (Bufbyte) t.c_cc[VEOF];
}
#else /* ! HAVE_TERMIOS */
/* On Berkeley descendants, the following IOCTL's retrieve the
{
int filedesc = DEVICE_INFD (d);
-#if defined (I_SETSIG) && !defined(HPUX10)
+#if defined (I_SETSIG) && !defined(HPUX10) && !defined(LINUX)
{
int events=0;
ioctl (filedesc, I_GETSIG, &events);
/* Set the parameters of the tty on FD according to the contents of
*SETTINGS. If FLUSHP is non-zero, we discard input.
- Return 0 if all went well, and -1 if anything failed. */
+ Return 0 if all went well, and -1 if anything failed.
+ #### All current callers use FLUSHP == 0. */
int
emacs_set_tty (int fd, struct emacs_tty *settings, int flushp)
input_fd = CONSOLE_TTY_DATA (con)->infd;
output_fd = CONSOLE_TTY_DATA (con)->outfd;
- EMACS_GET_TTY (input_fd, &CONSOLE_TTY_DATA (con)->old_tty);
+ emacs_get_tty (input_fd, &CONSOLE_TTY_DATA (con)->old_tty);
tty = CONSOLE_TTY_DATA (con)->old_tty;
con->tty_erase_char = Qnil;
}
else
{
- tty.main.c_cc[VINTR] = CDISABLE;
- tty.main.c_cc[VQUIT] = CDISABLE;
+ tty.main.c_cc[VINTR] = _POSIX_VDISABLE;
+ tty.main.c_cc[VQUIT] = _POSIX_VDISABLE;
}
tty.main.c_cc[VMIN] = 1; /* Input should wait for at
least 1 char */
tty.main.c_cc[VTIME] = 0; /* no matter how long that takes. */
#ifdef VSWTCH
- tty.main.c_cc[VSWTCH] = CDISABLE; /* Turn off shell layering use
- of C-z */
+ tty.main.c_cc[VSWTCH] = _POSIX_VDISABLE; /* Turn off shell layering use
+ of C-z */
#endif /* VSWTCH */
/* There was some conditionalizing here on (mips or TCATTR), but
I think that's wrong. There was one report of C-y (DSUSP) not being
disabled on HP9000s700 systems, and this might fix it. */
#ifdef VSUSP
- tty.main.c_cc[VSUSP] = CDISABLE;/* Turn off mips handling of C-z. */
+ tty.main.c_cc[VSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-z. */
#endif /* VSUSP */
#ifdef V_DSUSP
- tty.main.c_cc[V_DSUSP] = CDISABLE; /* Turn off mips handling of C-y. */
+ tty.main.c_cc[V_DSUSP] = _POSIX_VDISABLE; /* Turn off mips handling of C-y. */
#endif /* V_DSUSP */
#ifdef VDSUSP /* Some systems have VDSUSP, some have V_DSUSP. */
- tty.main.c_cc[VDSUSP] = CDISABLE;
+ tty.main.c_cc[VDSUSP] = _POSIX_VDISABLE;
#endif /* VDSUSP */
#ifdef VLNEXT
- tty.main.c_cc[VLNEXT] = CDISABLE;
+ tty.main.c_cc[VLNEXT] = _POSIX_VDISABLE;
#endif /* VLNEXT */
#ifdef VREPRINT
- tty.main.c_cc[VREPRINT] = CDISABLE;
+ tty.main.c_cc[VREPRINT] = _POSIX_VDISABLE;
#endif /* VREPRINT */
#ifdef VWERASE
- tty.main.c_cc[VWERASE] = CDISABLE;
+ tty.main.c_cc[VWERASE] = _POSIX_VDISABLE;
#endif /* VWERASE */
#ifdef VDISCARD
- tty.main.c_cc[VDISCARD] = CDISABLE;
+ tty.main.c_cc[VDISCARD] = _POSIX_VDISABLE;
#endif /* VDISCARD */
#ifdef VSTART
- tty.main.c_cc[VSTART] = CDISABLE;
+ tty.main.c_cc[VSTART] = _POSIX_VDISABLE;
#endif /* VSTART */
#ifdef VSTRT
- tty.main.c_cc[VSTRT] = CDISABLE; /* called VSTRT on some systems */
+ tty.main.c_cc[VSTRT] = _POSIX_VDISABLE; /* called VSTRT on some systems */
#endif /* VSTART */
#ifdef VSTOP
- tty.main.c_cc[VSTOP] = CDISABLE;
+ tty.main.c_cc[VSTOP] = _POSIX_VDISABLE;
#endif /* VSTOP */
#ifdef SET_LINE_DISCIPLINE
- /* Need to explicitely request TERMIODISC line discipline or
+ /* Need to explicitly request TERMIODISC line discipline or
Ultrix's termios does not work correctly. */
tty.main.c_line = SET_LINE_DISCIPLINE;
#endif
tty.ltchars = new_ltchars;
#endif /* HAVE_LTCHARS */
- EMACS_SET_TTY (input_fd, &tty, 0);
+ emacs_set_tty (input_fd, &tty, 0);
/* This code added to insure that, if flow-control is not to be used,
we have an unlocked terminal at the start. */
{
struct emacs_tty tty;
- EMACS_GET_TTY (DEVICE_INFD (d), &tty);
+ emacs_get_tty (DEVICE_INFD (d), &tty);
return EMACS_TTY_TABS_OK (&tty);
}
#endif
assert (DEVICE_TTY_P (d));
input_fd = DEVICE_INFD (d);
- EMACS_GET_TTY (input_fd, &s);
+ emacs_get_tty (input_fd, &s);
#if defined (HAVE_TERMIO) || defined (HAVE_TERMIOS)
eight_bit = (s.main.c_cflag & CSIZE) == CS8;
fsync (output_fd);
#endif
- while (EMACS_SET_TTY (input_fd, &CONSOLE_TTY_DATA (con)->old_tty, 0)
+ while (emacs_set_tty (input_fd, &CONSOLE_TTY_DATA (con)->old_tty, 0)
< 0 && errno == EINTR)
;
else
#endif
if (DEVICE_STREAM_P (d))
- fflush (CONSOLE_STREAM_DATA (XCONSOLE (DEVICE_CONSOLE (d)))->outfd);
+ fflush (CONSOLE_STREAM_DATA (XCONSOLE (DEVICE_CONSOLE (d)))->out);
#if defined(SIGIO) && !defined(BROKEN_SIGIO)
if (!DEVICE_STREAM_P (d))
{
/* limits of text/data segments */
/************************************************************************/
-/* Note that VMS compiler won't accept defined (CANNOT_DUMP). */
#ifndef CANNOT_DUMP
#define NEED_STARTS
#endif
*/
#ifdef __cplusplus
- extern "C" int _start ();
+ extern "C" int _start (void);
#else
- extern int _start ();
+ extern int _start (void);
#endif
#ifndef HAVE_TEXT_START
* at least on UniPlus, is temacs will have to be made unshared so
* that text and data are contiguous. Then once loadup is complete,
* unexec will produce a shared executable where the data can be
- * at the normal shared text boundry and the startofdata variable
+ * at the normal shared text boundary and the startofdata variable
* will be patched by unexec to the correct value.
*
*/
# ifndef CANNOT_DUMP
if (initialized)
# endif /* not CANNOT_DUMP */
- {
- struct hostent *hp = NULL;
- int count;
+ if (!strchr (hostname, '.'))
+ {
+ struct hostent *hp = NULL;
+ int count;
# ifdef TRY_AGAIN
- for (count = 0; count < 10; count++)
- {
- h_errno = 0;
+ for (count = 0; count < 10; count++)
+ {
+ h_errno = 0;
# endif
- /* Some systems can't handle SIGALARM/SIGIO in gethostbyname(). */
- stop_interrupts ();
- hp = gethostbyname (hostname);
- start_interrupts ();
+ /* Some systems can't handle SIGALARM/SIGIO in gethostbyname(). */
+ stop_interrupts ();
+ hp = gethostbyname (hostname);
+ start_interrupts ();
# ifdef TRY_AGAIN
- if (! (hp == 0 && h_errno == TRY_AGAIN))
- break;
- Fsleep_for (make_int (1));
- }
+ if (! (hp == 0 && h_errno == TRY_AGAIN))
+ break;
+ Fsleep_for (make_int (1));
+ }
# endif
- if (hp)
- {
- CONST char *fqdn = (CONST char *) hp->h_name;
-
- if (!strchr (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 && !strchr (*alias, '.'))
- alias++;
- if (*alias)
- fqdn = *alias;
- }
- hostname = (char *) alloca (strlen (fqdn) + 1);
- strcpy (hostname, fqdn);
- }
- }
+ if (hp)
+ {
+ CONST char *fqdn = (CONST char *) hp->h_name;
+
+ if (!strchr (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 && !strchr (*alias, '.'))
+ alias++;
+ if (*alias)
+ fqdn = *alias;
+ }
+ hostname = (char *) alloca (strlen (fqdn) + 1);
+ strcpy (hostname, fqdn);
+ }
+ }
# endif /* HAVE_SOCKETS */
Vsystem_name = build_string (hostname);
#endif /* HAVE_GETHOSTNAME */
/* Ben sez: read Dick Gabriel's essay about the Worse Is Better
approach to programming and its connection to the silly
- interruptible-system-call business. To find it, look at
- Jamie's home page (http://www.netscape.com/people/jwz). */
+ interruptible-system-call business. To find it, look on
+ Jamie's home page (http://www.jwz.org/worse-is-better.html). */
#ifdef ENCAPSULATE_OPEN
int
{
int rtnval;
while ((rtnval = open (path, oflag, mode)) == -1
- && (errno == EINTR));
+ && (errno == EINTR))
+ DO_NOTHING;
return rtnval;
}
#else
#ifdef ENCAPSULATE_CLOSE
int
-sys_close (int fd)
+sys_close (int filedes)
{
#ifdef INTERRUPTIBLE_CLOSE
int did_retry = 0;
REGISTER int rtnval;
- while ((rtnval = close (fd)) == -1
+ while ((rtnval = close (filedes)) == -1
&& (errno == EINTR))
did_retry = 1;
return rtnval;
#else
- return close (fd);
+ return close (filedes);
#endif
}
#endif /* ENCAPSULATE_CLOSE */
-int
+ssize_t
sys_read_1 (int fildes, void *buf, size_t nbyte, int allow_quit)
{
- int rtnval;
+ ssize_t rtnval;
/* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
while ((rtnval = read (fildes, buf, nbyte)) == -1
}
#ifdef ENCAPSULATE_READ
-int
+ssize_t
sys_read (int fildes, void *buf, size_t nbyte)
{
return sys_read_1 (fildes, buf, nbyte, 0);
}
#endif /* ENCAPSULATE_READ */
-int
+ssize_t
sys_write_1 (int fildes, CONST void *buf, size_t nbyte, int allow_quit)
{
- int rtnval;
- int bytes_written = 0;
+ ssize_t bytes_written = 0;
CONST char *b = (CONST char *) buf;
/* No harm in looping regardless of the INTERRUPTIBLE_IO setting. */
while (nbyte > 0)
{
- rtnval = write (fildes, b, nbyte);
+ ssize_t rtnval = write (fildes, b, nbyte);
if (allow_quit)
REALLY_QUIT;
if (errno == EINTR)
continue;
else
- return (bytes_written ? bytes_written : -1);
+ return bytes_written ? bytes_written : -1;
}
b += rtnval;
nbyte -= rtnval;
bytes_written += rtnval;
}
- return (bytes_written);
+ return bytes_written;
}
#ifdef ENCAPSULATE_WRITE
-int
+ssize_t
sys_write (int fildes, CONST void *buf, size_t nbyte)
{
return sys_write_1 (fildes, buf, nbyte, 0);
#elif defined (INTERRUPTIBLE_OPEN)
{
FILE *rtnval;
- while (!(rtnval = fopen (path, type)) && (errno == EINTR));
+ while (!(rtnval = fopen (path, type)) && (errno == EINTR))
+ DO_NOTHING;
return rtnval;
}
#else
#endif /* ENCAPSULATE_READLINK */
+#ifdef ENCAPSULATE_FSTAT
+int
+sys_fstat (int fd, struct stat *buf)
+{
+ return fstat (fd, buf);
+}
+#endif /* ENCAPSULATE_FSTAT */
+
+
#ifdef ENCAPSULATE_STAT
int
sys_stat (CONST char *path, struct stat *buf)
int fd; /* file descriptor for read */
struct stat sbuf; /* result of fstat */
- fd = sys_open (filename, 0);
+ fd = sys_open (filename, O_RDONLY);
if (fd < 0)
return 0;
{
case -1: /* Error in fork() */
- return (-1); /* Errno is set already */
+ return -1; /* Errno is set already */
case 0: /* Child process */
{
/*
- * Cheap hack to set mode of new directory. Since this
- * child process is going away anyway, we zap its umask.
- * ####, this won't suffice to set SUID, SGID, etc. on this
- * directory. Does anybody care?
- */
+ * Cheap hack to set mode of new directory. Since this
+ * child process is going away anyway, we zap its umask.
+ * ####, this won't suffice to set SUID, SGID, etc. on this
+ * directory. Does anybody care?
+ */
status = umask (0); /* Get current umask */
status = umask (status | (0777 & ~dmode)); /* Set for mkdir */
- fd = sys_open ("/dev/null", 2);
+ fd = sys_open ("/dev/null", O_RDWR);
if (fd >= 0)
{
- dup2 (fd, 0);
- dup2 (fd, 1);
- dup2 (fd, 2);
+ if (fd != STDIN_FILENO) dup2 (fd, STDIN_FILENO);
+ if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
+ if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
}
execl ("/bin/mkdir", "mkdir", dpath, (char *) 0);
_exit (-1); /* Can't exec /bin/mkdir */
return (-1); /* Errno is set already */
case 0: /* Child process */
- fd = sys_open("/dev/null", 2);
+ fd = sys_open("/dev/null", O_RDWR);
if (fd >= 0)
{
- dup2 (fd, 0);
- dup2 (fd, 1);
- dup2 (fd, 2);
+ if (fd != STDIN_FILENO) dup2 (fd, STDIN_FILENO);
+ if (fd != STDOUT_FILENO) dup2 (fd, STDOUT_FILENO);
+ if (fd != STDERR_FILENO) dup2 (fd, STDERR_FILENO);
}
execl ("/bin/rmdir", "rmdir", dpath, (char *) 0);
_exit (-1); /* Can't exec /bin/mkdir */
wait_for_termination (cpid);
}
- if (synch_process_death != 0 || synch_process_retcode != 0)
+ if (synch_process_death != 0 ||
+ synch_process_retcode != 0)
{
errno = EIO; /* We don't know why, but */
return -1; /* /bin/rmdir failed */