summaryrefslogtreecommitdiff
path: root/pc/popen.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2013-06-01 13:03:29 +0300
committerEli Zaretskii <eliz@gnu.org>2013-06-01 13:03:29 +0300
commit5482bf19246965d6839fe9df1aec0785f0b1a329 (patch)
tree818777446f62f531462f2b64b70d9868bcdcaa95 /pc/popen.c
parenta25b9b39ac2c49b822328414240061f6d22ddef2 (diff)
downloadgawk-5482bf19246965d6839fe9df1aec0785f0b1a329.tar.gz
Support |& on MS-Windows, both for sockets and for pipes.
io.c (SHUT_RD) [SD_RECEIVE]: Define to SD_RECEIVE. (SHUT_WR) [SD_SEND]: Define to SD_SEND. (SHUT_RDWR) [SD_BOTH]: Define to SD_BOTH. (FD_TO_SOCKET, closemaybesocket) [!FD_TO_SOCKET]: New macros. (SOCKET_TO_FD, SOCKET) [!SOCKET_TO_FD]: New macros. (PIPES_SIMULATED): Define only for DJGPP. (pipe) [__MINGW32__]: Define to call _pipe, unless PIPES_SIMULATED is defined. (init_io) [HAVE_SOCKETS]: Call init_sockets. (iop_close, socketopen): Call closemaybesocket instead of close. (redirect) [__MINGW32__]: Call wait_any with a non-zero argument. (devopen) [__EMX__ || __MINGW32__]: Don't call stat on network pseudo-filenames. (two_way_open) [HAVE_SOCKETS]: Switch input and output to binary mode if appropriate. (two_way_open) [!PIPES_SIMULATED]: Use the __EMX__ code for MinGW as well. [__MINGW32__] Call spawnl to invoke $ComSpec and pass it a suitably quoted command line. (two_way_open) [__MINGW32__]: Wait only for a specified process ID. If successful, update the exit status of the exited process. Don't use signals that are undefined on MinGW. (two_way_open) [!PIPES_SIMULATED]: Use the __EMX__ code for MinGW as well. (min): Define only if not already defined. (read_with_timeout) [__MINGW32__]: Allow reading from sockets with timeout. (gawk_fclose) [__MINGW32__]: Close the underlying socket as well. getopt.c: Include stdlib.h for MinGW as well. pc/popen.h (SIGKILL) [__MINGW32__]: Define. (kill, quote_cmd): New prototypes. pc/popen.c: Include popen.h and errno.h. (popen, pclose, system): Undefine macros. (WIN32_LEAN_AND_MEAN) [__MINGW32__]: Define and include windows.h. (kill, quote_cmd) [!PIPES_SIMULATED]: New functions. (os_popen): Make the function definition match its prototype exactly. pc/gawkmisc.pc [HAVE_SOCKETS]: Include socket.h and windows.h. (socket, setsockopt, bind, connect, listen, accept, recvfrom) (shutdown): Undefine macros. (os_close_on_exec) [__MINGW32__]: Non-trivial implementation. (init_sockets, socket_to_fd, w32_socket, w32_setsockopt) (w32_bind, w32_connect, w32_listen, w32_accept, valid_socket) (w32_closesocket, w32_recvfrom, w32_shutdown) [HAVE_SOCKETS]: New functions for MinGW, emulate Posix sockets specified by file descriptors. pc/config.h (HAVE_GETADDRINFO, HAVE_SOCKADDR_STORAGE) (HAVE_SOCKETS) [__MINGW32__]: Define. pc/config.sed (HAVE_GETADDRINFO, HAVE_SOCKADDR_STORAGE) (HAVE_SOCKETS) [__MINGW32__]: Define. pc/Makefile.tst (fmtspcl): Announce expected failure only if not built with MPFR. (inetecht, inetdayt): For MinGW, warn about time-outs. (beginfile1, clos1way, getlndir): Announce expected failure only with DJGPP. (exit): Describe the failure on MinGW. (readdir): Explain why test might fail with bad ls.exe. pc/Makefile (mingw32, mingw32-readline, mingw32-mpfr) (mingw32-readline-mpfr): Add -lws2_32 to the link flags. (gawkmisc$O): Depend on socket.h. (io$O): Depend on socket.h and in.h. (popen$O): New dependency. posix/gawkmisc.c (init_sockets): New dummy function. extension/filefuncs.c [_WIN32]: Define WIN32_LEAN_AND_MEAN before including windows.h. extension/readdir.c [__MINGW32__]: Define WIN32_LEAN_AND_MEAN before including windows.h. extension/filefuncs.c [HAVE_GETSYSTEMTIMEASFILETIME]: Define WIN32_LEAN_AND_MEAN before including windows.h. test/clos1way.awk: Don't use features of Posix shells, to allow this test to work on Windows. test/beginfile2.sh: Leave one blank between the left quote and the following slash. Use non-absolute name for a non-existent file. This is to avoid breakage on Windows due to MSYS transformation of Posix style /foo/bar absolute file names. test/beginfile2.ok: Adapt to changes in beginfile2.sh.
Diffstat (limited to 'pc/popen.c')
-rw-r--r--pc/popen.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/pc/popen.c b/pc/popen.c
index 97ff2645..399e250a 100644
--- a/pc/popen.c
+++ b/pc/popen.c
@@ -3,6 +3,11 @@
#include <io.h>
#include <string.h>
#include <process.h>
+#include <errno.h>
+#include "popen.h"
+#undef popen
+#undef pclose
+#undef system
#ifndef _NFILE
#define _NFILE 40
@@ -26,6 +31,9 @@ static struct {
#if defined(__MINGW32__)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
static int
unixshell(char *p)
{
@@ -127,13 +135,75 @@ os_system(const char *cmd)
unlink_and_free(cmd1);
return(i);
}
+
+#ifndef PIPES_SIMULATED
+int
+kill (int pid, int sig)
+{
+ HANDLE ph;
+ int retval = 0;
+
+ /* We only support SIGKILL. */
+ if (sig != SIGKILL)
+ {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ ph = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
+ if (ph)
+ {
+ BOOL status = TerminateProcess(ph, -1);
+
+ if (!status)
+ {
+ errno = EPERM;
+ retval = -1;
+ }
+ }
+ else
+ {
+ /* If we cannot open the process, it means we eaither aren't
+ allowed to (e.g., a process of another user), or such a
+ process doesn't exist. */
+ switch (GetLastError ())
+ {
+ case ERROR_ACCESS_DENIED:
+ errno = EPERM;
+ break;
+ default:
+ errno = ESRCH;
+ break;
+ }
+ retval = -1;
+ }
+ CloseHandle (ph);
+ return retval;
+}
+
+char *
+quote_cmd(const char *cmd)
+{
+ char *quoted;
+
+ /* The command will be invoked via cmd.exe, whose behavior wrt
+ quoted commands is to remove the first and the last quote
+ characters, and leave the rest (including any quote characters
+ inside the outer pair) intact. */
+ quoted = malloc(strlen (cmd) + 2 + 1);
+ sprintf(quoted, "\"%s\"", cmd);
+
+ return quoted;
+}
+#endif
+
#else /* !__MINGW32__ */
#define os_system(cmd) system(cmd)
#endif
FILE *
-os_popen(const char *command, char *mode )
+os_popen(const char *command, const char *mode )
{
FILE *current;
char *name;