summaryrefslogtreecommitdiff
path: root/pc
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
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')
-rw-r--r--pc/ChangeLog42
-rw-r--r--pc/Makefile14
-rw-r--r--pc/Makefile.tst18
-rw-r--r--pc/config.h12
-rw-r--r--pc/config.sed12
-rw-r--r--pc/gawkmisc.pc177
-rw-r--r--pc/in.h1
-rw-r--r--pc/popen.c72
-rw-r--r--pc/popen.h5
-rw-r--r--pc/socket.h42
10 files changed, 370 insertions, 25 deletions
diff --git a/pc/ChangeLog b/pc/ChangeLog
index 3cb6ce11..f1d1978b 100644
--- a/pc/ChangeLog
+++ b/pc/ChangeLog
@@ -1,3 +1,45 @@
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * popen.h (SIGKILL) [__MINGW32__]: Define.
+ (kill, quote_cmd): New prototypes.
+
+ * 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.
+
+ * 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.
+
+ * config.h (HAVE_GETADDRINFO, HAVE_SOCKADDR_STORAGE)
+ (HAVE_SOCKETS) [__MINGW32__]: Define.
+
+ * config.sed (HAVE_GETADDRINFO, HAVE_SOCKADDR_STORAGE)
+ (HAVE_SOCKETS) [__MINGW32__]: Define.
+
+ * 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.
+
+ * 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.
+
2013-05-27 Arnold D. Robbins <arnold@skeeve.com>
* config.h: Remove obsolete HAVE_ST_BLKSIZE.
diff --git a/pc/Makefile b/pc/Makefile
index 4152ed24..9d98cb1c 100644
--- a/pc/Makefile
+++ b/pc/Makefile
@@ -158,28 +158,29 @@ LMINGW32 = $(CC) $(LF) -o $@ $(GAWKOBJS) $(LF2)
mingw32:
$(MAK) all \
CC=gcc O=.o CF="-D__USE_MINGW_ANSI_STDIO -O2 -gdwarf-2 -g3" \
- OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" LF2=-lmsvcp60 RSP=
+ OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" \
+ LF2="-lws2_32 -lmsvcp60" RSP=
mingw32-readline:
$(MAK) all \
CC=gcc O=.o \
CF="-D__USE_MINGW_ANSI_STDIO -DHAVE_LIBREADLINE -O2 -gdwarf-2 -g3" \
OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" \
- LF2="-lreadline -lmsvcp60 -Wl,--enable-auto-import" RSP=
+ LF2="-lreadline -lws2_32 -lmsvcp60 -Wl,--enable-auto-import" RSP=
mingw32-mpfr:
$(MAK) all \
CC=gcc O=.o \
CF="-D__USE_MINGW_ANSI_STDIO -DHAVE_MPFR -O2 -gdwarf-2 -g3" \
OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" \
- LF2="-lmpfr -lgmp -lmsvcp60 -Wl,--enable-auto-import" RSP=
+ LF2="-lmpfr -lgmp -lws2_32 -lmsvcp60 -Wl,--enable-auto-import" RSP=
mingw32-readline-mpfr:
$(MAK) all \
CC=gcc O=.o \
CF="-D__USE_MINGW_ANSI_STDIO -DHAVE_LIBREADLINE -DHAVE_MPFR -O2 -gdwarf-2 -g3" \
OBJ=popen.o LNK=LMINGW32 LF="-gdwarf-2 -g3" \
- LF2="-lmpfr -lgmp -lreadline -lmsvcp60 -Wl,--enable-auto-import" RSP=
+ LF2="-lmpfr -lgmp -lreadline -lws2_32 -lmsvcp60 -Wl,--enable-auto-import" RSP=
# Define BIND for BINDless compiles, otherwise $($(BIND)) may break.
BIND = EMPTY
@@ -242,11 +243,11 @@ command$O debug$O: cmd.h
dfa$O: xalloc.h
-gawkmisc$O: pc/gawkmisc.pc
+gawkmisc$O: pc/gawkmisc.pc socket.h
getopt$O getopt1$O : getopt_int.h
-io$O: popen.h
+io$O: popen.h socket.h in.h
regex$O: regcomp.c regexec.c regex_internal.h
@@ -261,6 +262,7 @@ awkgram.c: awkgram.y
alloca$O: alloca.c
+popen$O: popen.h
install: install$(install)
-$(MAKE) -C extension install-extensions
diff --git a/pc/Makefile.tst b/pc/Makefile.tst
index cc188fda..6e6992c2 100644
--- a/pc/Makefile.tst
+++ b/pc/Makefile.tst
@@ -60,7 +60,7 @@
SHELL = /bin/sh
# Point to gawk
-AWK = AWKLIBPATH=../extension ../gawk.exe
+AWK = AWKLIBPATH=../extension $(AWKPROG)
# Also point to gawk but for DOS commands needing backslashes. We need
# the forward slash version too or 'arrayparam' fails.
AWK2 = '..\gawk.exe'
@@ -500,7 +500,7 @@ fmtspcl.ok: fmtspcl.tok
fmtspcl: fmtspcl.ok
@echo $@
- @echo Expect $@ to fail with MinGW
+ @echo Expect $@ to fail on MinGW if not built with MPFR
@$(AWK) $(AWKFLAGS) -f $(srcdir)/fmtspcl.awk --lint >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-if test -z "$$AWKFLAGS" ; then $(CMP) $@.ok _$@ && rm -f _$@ ; else \
$(CMP) $(srcdir)/$@-mpfr.ok _$@ && rm -f _$@ ; \
@@ -553,6 +553,7 @@ inetechu::
inetecht::
@echo Expect inetecht to fail with DJGPP.
+ @echo Expect inetecht to time out with MinGW after 20 sec.
@echo This test is for establishing TCP connections
# @$(AWK) 'BEGIN {print "" |& "/inet/tcp/0/127.0.0.1/9"}'
@-$(AWK) 'BEGIN {print "" |& "/inet/tcp/0/127.0.0.1/9"}'
@@ -567,6 +568,7 @@ inetdayu::
inetdayt::
@echo Expect inetdayt to fail with DJGPP.
+ @echo Expect inetdayt to time out with MinGW after 41 sec.
@echo This test is for bidirectional TCP transmission
# @$(AWK) 'BEGIN { print "" |& "/inet/tcp/0/127.0.0.1/13"; \
# "/inet/tcp/0/127.0.0.1/13" |& getline; print $0}'
@@ -820,7 +822,7 @@ printfbad2: printfbad2.ok
beginfile1::
@echo $@
- @echo Expect beginfile1 to fail with DJGPP and MinGW
+ @echo Expect beginfile1 to fail with DJGPP
@AWKPATH=$(srcdir) $(AWK) -f $@.awk $(srcdir)/$@.awk . ./no/such/file Makefile >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
@@ -868,7 +870,7 @@ next:
exit:
@echo $@
- @echo Expect exit to fail with MinGW
+ @echo Expect exit to fail with MinGW due to null vs nul difference
@-AWK="$(AWKPROG)" $(srcdir)/$@.sh > _$@ 2>&1
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
@@ -1010,7 +1012,7 @@ readdir:
echo If it does, try rerunning on an ext'[234]' filesystem. ; \
fi
@echo $@
- @echo This test may fail if $(LS) does not report full Windows file index as the inode
+ @echo This test may fail on MinGW if $(LS) does not report full Windows file index as the inode
@$(AWK) -f $(srcdir)/readdir.awk $(top_srcdir) > _$@
@$(LS) -afli $(top_srcdir) | sed 1d | $(AWK) -f $(srcdir)/readdir0.awk -v extout=_$@ > $@.ok
@-$(CMP) $@.ok _$@ && rm -f $@.ok _$@
@@ -1998,8 +2000,8 @@ backw:
clos1way:
@echo $@
- @echo Expect clos1way to fail with DJGPP and MinGW.
- @AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
+ @echo Expect clos1way to fail with DJGPP.
+ @AWKPATH=$(srcdir) LC_ALL=C $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
delsub:
@@ -2084,7 +2086,7 @@ gensub2:
getlndir:
@echo $@
- @echo Expect getlndir to fail with DJGPP and MinGW.
+ @echo Expect getlndir to fail with DJGPP.
@AWKPATH=$(srcdir) $(AWK) -f $@.awk >_$@ 2>&1 || echo EXIT CODE: $$? >>_$@
@-$(CMP) $(srcdir)/$@.ok _$@ && rm -f _$@
diff --git a/pc/config.h b/pc/config.h
index 1d373b01..92e1b4e3 100644
--- a/pc/config.h
+++ b/pc/config.h
@@ -59,7 +59,9 @@
#define HAVE_FMOD 1
/* have getaddrinfo */
-#undef HAVE_GETADDRINFO
+#ifdef __MINGW32__
+#define HAVE_GETADDRINFO 1
+#endif
/* Define to 1 if you have the `getgrent' function. */
#undef HAVE_GETGRENT
@@ -210,10 +212,14 @@
#endif
/* newer systems define this type here */
-#undef HAVE_SOCKADDR_STORAGE
+#ifdef __MINGW32__
+#define HAVE_SOCKADDR_STORAGE 1
+#endif
/* we have sockets on this system */
-#undef HAVE_SOCKETS
+#ifdef __MINGW32__
+#define HAVE_SOCKETS 1
+#endif
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
diff --git a/pc/config.sed b/pc/config.sed
index 18d33297..e18a6e68 100644
--- a/pc/config.sed
+++ b/pc/config.sed
@@ -48,6 +48,10 @@ s/^#undef HAVE_ATEXIT *$/#define HAVE_ATEXIT 1/
#endif
s/^#undef HAVE_FCNTL_H *$/#define HAVE_FCNTL_H 1/
s/^#undef HAVE_FMOD *$/#define HAVE_FMOD 1/
+/^#undef HAVE_GETADDRINFO *$/c\
+#ifdef __MINGW32__\
+#define HAVE_GETADDRINFO 1\
+#endif
/^#undef HAVE_INTMAX_T *$/c\
#ifdef __MINGW32__\
#define HAVE_INTMAX_T 1\
@@ -122,6 +126,14 @@ s/^#undef HAVE_MKTIME *$/#define HAVE_MKTIME 1/
#ifdef __MINGW32__\
#define HAVE_SNPRINTF 1\
#endif
+/^#undef HAVE_SOCKADDR_STORAGE *$/c\
+#ifdef __MINGW32__\
+#define HAVE_SOCKADDR_STORAGE 1\
+#endif
+/^#undef HAVE_SOCKETS *$/c\
+#ifdef __MINGW32__\
+#define HAVE_SOCKETS 1\
+#endif
s/^#undef HAVE_STDARG_H *$/#define HAVE_STDARG_H 1/
/^#undef HAVE_STDDEF_H *$/c\
#ifdef __GNUC__\
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc
index 5e412d71..ce45b6d8 100644
--- a/pc/gawkmisc.pc
+++ b/pc/gawkmisc.pc
@@ -42,6 +42,24 @@ static char* _os2_unixroot(const char *path);
static const char* _os2_unixroot_path(const char *path);
#endif
+#ifdef __MINGW32__
+#ifdef HAVE_SOCKETS
+#include <socket.h>
+
+#undef socket
+#undef setsockopt
+#undef bind
+#undef connect
+#undef listen
+#undef accept
+#undef recvfrom
+#undef shutdown
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
/* gawk_name --- pull out the "gawk" part from how the OS called us */
char *
@@ -205,15 +223,19 @@ os_close_on_exec(fd, name, what, dir)
int fd;
const char *name, *what, *dir;
{
-#if ! defined(_MSC_VER) && ! defined(__MINGW32__)
-# if (defined(__DJGPP__) && (__DJGPP__ > 2 || __DJGPP_MINOR__ >= 4)) || defined __EMX__
+#if (defined(__DJGPP__) && (__DJGPP__ > 2 || __DJGPP_MINOR__ >= 4)) || defined __EMX__
if (fd <= 2) /* sanity */
return;
if (fcntl(fd, F_SETFD, 1) < 0)
warning("%s %s `%s': could not set close-on-exec: %s",
what, dir, name, strerror(errno));
-# endif
+#endif
+#ifdef __MINGW32__
+ HANDLE fh = (HANDLE)_get_osfhandle(fd);
+
+ if (fh && fh != INVALID_HANDLE_VALUE)
+ SetHandleInformation(fh, HANDLE_FLAG_INHERIT, 0);
#endif
}
@@ -562,8 +584,6 @@ unsetenv (const char *name)
return setenv (name, "", 1);
}
-#include <windows.h>
-
int
usleep(unsigned int usec)
{
@@ -693,7 +713,152 @@ dlsym (void *handle, const char *name)
return (void *)addr;
}
-#endif
+#endif /* DYNAMIC */
+
+#ifdef HAVE_SOCKETS
+
+void
+init_sockets(void)
+{
+ WSADATA winsockData;
+ int errcode;
+
+ if ((errcode = WSAStartup (0x101, &winsockData)) != 0
+ || winsockData.wVersion != 0x101)
+ fatal(_("cannot start Winsock (%d)"), errcode);
+}
+
+int
+socket_to_fd(SOCKET s)
+{
+ return (s == INVALID_SOCKET
+ ? INVALID_HANDLE
+ : _open_osfhandle (s, O_BINARY | O_NOINHERIT));
+}
+
+int
+w32_socket(int family, int type, int protocol)
+{
+ /* We need to use WSASocket rather than socket, since the latter
+ creates overlapped sockets that cannot be used in file I/O
+ APIs. */
+ SOCKET s = WSASocket (family, type, protocol, NULL, 0, 0);
+
+ if (s == INVALID_SOCKET)
+ {
+ switch (WSAGetLastError ())
+ {
+ case WSAEMFILE:
+ errno = EMFILE;
+ break;
+ case WSANOTINITIALISED:
+ case WSAENETDOWN:
+ errno = EACCES;
+ break;
+ case WSAENOBUFS:
+ errno = ENOMEM;
+ break;
+ case WSAEFAULT:
+ errno = EFAULT;
+ break;
+ default:
+ errno = EINVAL;
+ break;
+ }
+ }
+
+ return socket_to_fd (s);
+}
+
+int
+w32_setsockopt (int fd, int level, int optname, const char *optval, int optlen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return setsockopt (s, level, optname, optval, optlen);
+}
+
+int
+w32_bind (int fd, const struct sockaddr *name, int namelen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return bind (s, name, namelen);
+}
+
+int
+w32_connect (int fd, const struct sockaddr *name, int namelen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return connect (s, name, namelen);
+}
+
+int
+w32_listen (int fd, int backlog)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return listen (s, backlog);
+}
+
+int
+w32_accept (int fd, struct sockaddr *addr, int *addrlen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return socket_to_fd (accept (s, addr, addrlen));
+}
+
+SOCKET
+valid_socket (int fd)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+ int ov, ol = 4;
+
+ if (s == INVALID_SOCKET
+ || (getsockopt (s, SOL_SOCKET, SO_TYPE, (char *)&ov, &ol) == SOCKET_ERROR
+ && WSAGetLastError() == WSAENOTSOCK))
+ return (SOCKET)0;
+ return s;
+}
+
+int
+w32_closesocket (int fd)
+{
+ SOCKET s = valid_socket (fd);
+ int res1, res2 = 0;
+
+ if (!s && fd == FAKE_FD_VALUE)
+ return 0;
+
+ res1 = close (fd);
+ if (s)
+ res2 = closesocket (s);
+
+ if (res1 == -1 || res2 == SOCKET_ERROR)
+ return -1;
+ return 0;
+}
+
+int
+w32_recvfrom (int fd, char *buf, int len, int flags,
+ struct sockaddr *from, int *fromlen)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return recvfrom (s, buf, len, flags, from, fromlen);
+}
+
+int
+w32_shutdown (int fd, int how)
+{
+ SOCKET s = FD_TO_SOCKET (fd);
+
+ return shutdown (s, how);
+}
+
+#endif /* HAVE_SOCKETS */
#endif /* __MINGW32__ */
diff --git a/pc/in.h b/pc/in.h
new file mode 100644
index 00000000..d0833805
--- /dev/null
+++ b/pc/in.h
@@ -0,0 +1 @@
+/* A dummy in.h for pc/ systems. */
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;
diff --git a/pc/popen.h b/pc/popen.h
index 9a04299c..b86c00f0 100644
--- a/pc/popen.h
+++ b/pc/popen.h
@@ -12,6 +12,9 @@
extern int os_pclose( FILE * );
# ifdef __MINGW32__
# define system(c) os_system(c)
- extern int os_system( const char * );
+ extern int os_system( const char * );
+# define SIGKILL 9
+ extern int kill( int, int );
+ extern char *quote_cmd( const char * );
# endif /* __MINGW32__ */
#endif /* !__DJGPP__ */
diff --git a/pc/socket.h b/pc/socket.h
new file mode 100644
index 00000000..41dd23cf
--- /dev/null
+++ b/pc/socket.h
@@ -0,0 +1,42 @@
+/* An emulation for socket.h header for pc/ systems. */
+
+#ifndef GAWK_SOCKET_H
+#define GAWK_SOCKET_H
+
+#ifdef __MINGW32__
+
+#include <io.h>
+
+#define _WIN32_WINNT 0x501
+#include <winsock2.h>
+#include <ws2tcpip.h>
+
+#define socket(f,t,p) w32_socket(f,t,p)
+#define setsockopt(f,l,o,v,s) w32_setsockopt(f,l,o,v,s)
+#define bind(f,a,l) w32_bind(f,a,l)
+#define connect(f,a,l) w32_connect(f,a,l)
+#define listen(f,b) w32_listen(f,b)
+#define accept(f,a,l) w32_accept(f,a,l)
+#define closemaybesocket(f) w32_closesocket(f)
+#define recvfrom(f,b,l,fl,fr,ln) w32_recvfrom(f,b,l,fl,fr,ln)
+#define shutdown(f,h) w32_shutdown(f,h)
+
+#define SOCKET_TO_FD(s) socket_to_fd(s)
+#define FD_TO_SOCKET(fd) \
+ ((fd) == INVALID_HANDLE ? INVALID_SOCKET : _get_osfhandle(fd))
+
+int w32_socket (int, int, int);
+int w32_setsockopt (int, int, int, const char *, int);
+int w32_bind (int, const struct sockaddr *, int);
+int w32_connect (int, const struct sockaddr *, int);
+int w32_listen (int, int);
+int w32_accept (int, struct sockaddr *, int *);
+int w32_closesocket (int);
+int w32_recvfrom (int, char *, int, int, struct sockaddr *, int *);
+int w32_shutdown (int, int);
+int socket_to_fd (SOCKET);
+SOCKET valid_socket (int);
+
+#endif /* __MINGW32__ */
+
+#endif /* GAWK_SOCKET_H */