summaryrefslogtreecommitdiff
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
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.
-rw-r--r--ChangeLog33
-rw-r--r--extension/ChangeLog11
-rw-r--r--extension/filefuncs.c1
-rw-r--r--extension/readdir.c1
-rw-r--r--extension/time.c1
-rw-r--r--getopt.c3
-rw-r--r--io.c177
-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
-rw-r--r--posix/ChangeLog4
-rw-r--r--posix/gawkmisc.c7
-rw-r--r--test/ChangeLog12
-rw-r--r--test/beginfile2.ok10
-rwxr-xr-xtest/beginfile2.sh40
-rw-r--r--test/clos1way.awk2
23 files changed, 613 insertions, 84 deletions
diff --git a/ChangeLog b/ChangeLog
index 6dfee660..2f4dd3d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * 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.
+
2013-05-30 Arnold D. Robbins <arnold@skeeve.com>
More profiling fixes:
diff --git a/extension/ChangeLog b/extension/ChangeLog
index 02b426ee..2bffccf8 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,14 @@
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * filefuncs.c [_WIN32]: Define WIN32_LEAN_AND_MEAN before
+ including windows.h.
+
+ * readdir.c [__MINGW32__]: Define WIN32_LEAN_AND_MEAN before
+ including windows.h.
+
+ * filefuncs.c [HAVE_GETSYSTEMTIMEASFILETIME]: Define
+ WIN32_LEAN_AND_MEAN before including windows.h.
+
2013-05-29 Arnold D. Robbins <arnold@skeeve.com>
* configure.ac: Add <sys/param.h> header check.
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index 0afed056..5ef0e61b 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -77,6 +77,7 @@
#define major(s) (s)
#define minor(s) (0)
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/* get_inode --- get the inode of a file */
diff --git a/extension/readdir.c b/extension/readdir.c
index 9d53ad9a..ed770faa 100644
--- a/extension/readdir.c
+++ b/extension/readdir.c
@@ -51,6 +51,7 @@
#endif
#ifdef __MINGW32__
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
diff --git a/extension/time.c b/extension/time.c
index cf39ccc2..9fadfe54 100644
--- a/extension/time.c
+++ b/extension/time.c
@@ -62,6 +62,7 @@ int plugin_is_GPL_compatible;
#include <time.h>
#endif
#if defined(HAVE_GETSYSTEMTIMEASFILETIME)
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
diff --git a/getopt.c b/getopt.c
index 053a4604..7679991d 100644
--- a/getopt.c
+++ b/getopt.c
@@ -57,11 +57,12 @@
/* This needs to come after some library #include
to get __GNU_LIBRARY__ defined. */
-#if defined (__GNU_LIBRARY__) || defined (__CYGWIN__) || defined(__DJGPP__) || defined(__APPLE__)
+#if defined (__GNU_LIBRARY__) || defined (__CYGWIN__) || defined(__DJGPP__) || defined(__APPLE__) || defined(__MINGW32__)
/* Don't include stdlib.h for
* non-GNU C libraries
* non-Cygwin
* non-DJGPP
+ * non-MinGW
* because some of them contain conflicting prototypes for getopt. */
# include <stdlib.h>
# include <unistd.h>
diff --git a/io.c b/io.c
index 4f682622..c8b1f9a1 100644
--- a/io.c
+++ b/io.c
@@ -119,15 +119,38 @@
#ifdef HAVE_SOCKETS
#ifndef SHUT_RD
-#define SHUT_RD 0
+# ifdef SD_RECEIVE
+# define SHUT_RD SD_RECEIVE
+# else
+# define SHUT_RD 0
+# endif
#endif
#ifndef SHUT_WR
-#define SHUT_WR 1
+# ifdef SD_SEND
+# define SHUT_WR SD_SEND
+# else
+# define SHUT_WR 1
+# endif
#endif
#ifndef SHUT_RDWR
-#define SHUT_RDWR 2
+# ifdef SD_BOTH
+# define SHUT_RDWR SD_BOTH
+# else
+# define SHUT_RDWR 2
+# endif
+#endif
+
+/* MinGW defines non-trivial macros on pc/socket.h. */
+#ifndef FD_TO_SOCKET
+# define FD_TO_SOCKET(fd) (fd)
+# define closemaybesocket(fd) close(fd)
+#endif
+
+#ifndef SOCKET_TO_FD
+# define SOCKET_TO_FD(s) (s)
+# define SOCKET int
#endif
#endif /* HAVE_SOCKETS */
@@ -140,10 +163,16 @@
#undef TANDEM /* AIX defines this in one of its header files */
#endif
-#if defined(__DJGPP__) || defined(__MINGW32__)
+#ifdef __DJGPP__
#define PIPES_SIMULATED
#endif
+#ifdef __MINGW32__
+# ifndef PIPES_SIMULATED
+# define pipe(fds) _pipe(fds, 0, O_NOINHERIT)
+# endif
+#endif
+
#ifdef HAVE_MPFR
/* increment NR or FNR */
#define INCREMENT_REC(X) (do_mpfr && X == (LONG_MAX - 1)) ? \
@@ -265,6 +294,10 @@ init_io()
{
long tmout;
+#ifdef HAVE_SOCKETS
+ /* Only MinGW has a non-trivial implementation of this. */
+ init_sockets();
+#endif
/*
* N.B.: all these hacks are to minimize the effect
* on programs that do not care about timeout.
@@ -587,7 +620,7 @@ iop_close(IOBUF *iop)
|| iop->public.fd == fileno(stderr))
ret = remap_std_file(iop->public.fd);
else
- ret = close(iop->public.fd);
+ ret = closemaybesocket(iop->public.fd);
}
if (ret == -1)
@@ -739,7 +772,12 @@ redirect(NODE *redir_exp, int redirtype, int *errflg)
*/
if ((rp->flag & RED_EOF) != 0 && redirtype == redirect_pipein) {
if (rp->pid != -1)
+#ifdef __MINGW32__
+ /* MinGW cannot wait for any process. */
+ wait_any(rp->pid);
+#else
wait_any(0);
+#endif
}
#endif /* PIPES_SIMULATED */
@@ -1418,7 +1456,7 @@ socketopen(int family, int type, const char *localpname,
&& (clientsocket_fd = accept(socket_fd,
(struct sockaddr *) & remote_addr,
& namelen)) >= 0) {
- close(socket_fd);
+ closemaybesocket(socket_fd);
socket_fd = clientsocket_fd;
break;
}
@@ -1442,7 +1480,7 @@ socketopen(int family, int type, const char *localpname,
nextrres:
if (socket_fd != INVALID_HANDLE)
- close(socket_fd);
+ closemaybesocket(socket_fd);
socket_fd = INVALID_HANDLE;
rres = rres->ai_next;
}
@@ -1634,8 +1672,10 @@ strictopen:
/* On OS/2 and Windows directory access via open() is
not permitted. */
struct stat buf;
+ int l, f;
- if (stat(name, & buf) == 0 && S_ISDIR(buf.st_mode))
+ if (!inetfile(name, &l, &f)
+ && stat(name, & buf) == 0 && S_ISDIR(buf.st_mode))
errno = EISDIR;
}
#endif
@@ -1662,7 +1702,9 @@ two_way_open(const char *str, struct redirect *rp)
fd = devopen(str, "rw");
if (fd == INVALID_HANDLE)
return false;
- rp->output.fp = fdopen(fd, "w");
+ if ((BINMODE & BINMODE_OUTPUT) != 0)
+ os_setbinmode(fd, O_BINARY);
+ rp->output.fp = fdopen(fd, binmode("wb"));
if (rp->output.fp == NULL) {
close(fd);
return false;
@@ -1672,6 +1714,8 @@ two_way_open(const char *str, struct redirect *rp)
rp->output.gawk_fclose(rp->output.fp, rp->output.opaque);
return false;
}
+ if ((BINMODE & BINMODE_INPUT) != 0)
+ os_setbinmode(newfd, O_BINARY);
os_close_on_exec(fd, str, "socket", "to/from");
os_close_on_exec(newfd, str, "socket", "to/from");
rp->iop = iop_alloc(newfd, str, 0);
@@ -1929,8 +1973,11 @@ use_pipes:
int ptoc[2], ctop[2];
int pid;
int save_errno;
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__MINGW32__)
int save_stdout, save_stdin;
+#ifdef __MINGW32__
+ char *qcmd = NULL;
+#endif
#endif
if (pipe(ptoc) < 0)
@@ -1944,7 +1991,7 @@ use_pipes:
return false;
}
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__MINGW32__)
save_stdin = dup(0); /* duplicate stdin */
save_stdout = dup(1); /* duplicate stdout */
@@ -1987,7 +2034,13 @@ use_pipes:
os_close_on_exec(save_stdout, str, "pipe", "from"); /* saved stdout of the parent process */
/* stderr does NOT get dup'ed onto child's stdout */
+#ifdef __EMX__
pid = spawnl(P_NOWAIT, "/bin/sh", "sh", "-c", str, NULL);
+#else /* __MINGW32__ */
+ pid = spawnl(P_NOWAIT, getenv("ComSpec"), "cmd.exe", "/c",
+ qcmd = quote_cmd(str), NULL);
+ efree(qcmd);
+#endif
/* restore stdin and stdout */
close(1);
@@ -2015,7 +2068,7 @@ use_pipes:
return false;
}
-#else /* NOT __EMX__ */
+#else /* NOT __EMX__, NOT __MINGW32__ */
if ((pid = fork()) < 0) {
save_errno = errno;
close(ptoc[0]); close(ptoc[1]);
@@ -2042,9 +2095,13 @@ use_pipes:
execl("/bin/sh", "sh", "-c", str, NULL);
_exit(errno == ENOENT ? 127 : 126);
}
-#endif /* NOT __EMX__ */
+#endif /* NOT __EMX__, NOT __MINGW32__ */
/* parent */
+ if ((BINMODE & BINMODE_INPUT) != 0)
+ os_setbinmode(ctop[0], O_BINARY);
+ if ((BINMODE & BINMODE_OUTPUT) != 0)
+ os_setbinmode(ptoc[1], O_BINARY);
rp->pid = pid;
rp->iop = iop_alloc(ctop[0], str, 0);
find_input_parser(rp->iop);
@@ -2061,7 +2118,7 @@ use_pipes:
return false;
}
- rp->output.fp = fdopen(ptoc[1], "w");
+ rp->output.fp = fdopen(ptoc[1], binmode("w"));
rp->output.mode = "w";
rp->output.name = str;
if (rp->output.fp == NULL) {
@@ -2078,7 +2135,7 @@ use_pipes:
else
find_output_wrapper(& rp->output);
-#ifndef __EMX__
+#if !defined(__EMX__) && !defined(__MINGW32__)
os_close_on_exec(ctop[0], str, "pipe", "from");
os_close_on_exec(ptoc[1], str, "pipe", "from");
@@ -2110,15 +2167,31 @@ wait_any(int interesting) /* pid of interest, if any */
int status = 0;
struct redirect *redp;
- hstat = signal(SIGHUP, SIG_IGN);
istat = signal(SIGINT, SIG_IGN);
+#ifdef __MINGW32__
+ if (interesting < 0) {
+ status = -1;
+ pid = -1;
+ }
+ else
+ pid = _cwait(& status, interesting, 0);
+ if (pid == interesting && pid > 0) {
+ for (redp = red_head; redp != NULL; redp = redp->next)
+ if (interesting == redp->pid) {
+ redp->pid = -1;
+ redp->status = status;
+ break;
+ }
+ }
+#else
+ hstat = signal(SIGHUP, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
for (;;) {
-#ifdef HAVE_SYS_WAIT_H /* POSIX compatible sys/wait.h */
+# ifdef HAVE_SYS_WAIT_H /* POSIX compatible sys/wait.h */
pid = wait(& status);
-#else
+# else
pid = wait((union wait *) & status);
-#endif
+# endif
if (interesting && pid == interesting) {
break;
} else if (pid != -1) {
@@ -2133,8 +2206,9 @@ wait_any(int interesting) /* pid of interest, if any */
break;
}
signal(SIGHUP, hstat);
- signal(SIGINT, istat);
signal(SIGQUIT, qstat);
+#endif
+ signal(SIGINT, istat);
return status;
}
@@ -2145,8 +2219,11 @@ gawk_popen(const char *cmd, struct redirect *rp)
{
int p[2];
int pid;
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__MINGW32__)
int save_stdout;
+#ifdef __MINGW32__
+ char *qcmd = NULL;
+#endif
#endif
/*
@@ -2160,7 +2237,7 @@ gawk_popen(const char *cmd, struct redirect *rp)
if (pipe(p) < 0)
fatal(_("cannot open pipe `%s' (%s)"), cmd, strerror(errno));
-#ifdef __EMX__
+#if defined(__EMX__) || defined(__MINGW32__)
rp->iop = NULL;
save_stdout = dup(1); /* save stdout */
if (save_stdout == -1) {
@@ -2182,8 +2259,14 @@ gawk_popen(const char *cmd, struct redirect *rp)
os_close_on_exec(p[0], cmd, "pipe", "from"); /* pipe output: input of the parent process */
os_close_on_exec(save_stdout, cmd, "pipe", "from"); /* saved stdout of the parent process */
-
+
+#ifdef __EMX__
pid = spawnl(P_NOWAIT, "/bin/sh", "sh", "-c", cmd, NULL);
+#else /* __MINGW32__ */
+ pid = spawnl(P_NOWAIT, getenv("ComSpec"), "cmd.exe", "/c",
+ qcmd = quote_cmd(cmd), NULL);
+ efree(qcmd);
+#endif
/* restore stdout */
close(1);
@@ -2193,7 +2276,7 @@ gawk_popen(const char *cmd, struct redirect *rp)
}
close(save_stdout);
-#else /* NOT __EMX__ */
+#else /* NOT __EMX__, NOT __MINGW32__ */
if ((pid = fork()) == 0) {
if (close(1) == -1)
fatal(_("close of stdout in child failed (%s)"),
@@ -2205,20 +2288,22 @@ gawk_popen(const char *cmd, struct redirect *rp)
execl("/bin/sh", "sh", "-c", cmd, NULL);
_exit(errno == ENOENT ? 127 : 126);
}
-#endif /* NOT __EMX__ */
+#endif /* NOT __EMX__, NOT __MINGW32__ */
if (pid == -1) {
close(p[0]); close(p[1]);
fatal(_("cannot create child process for `%s' (fork: %s)"), cmd, strerror(errno));
}
rp->pid = pid;
-#ifndef __EMX__
+#if !defined(__EMX__) && !defined(__MINGW32__)
if (close(p[1]) == -1) {
close(p[0]);
fatal(_("close of pipe failed (%s)"), strerror(errno));
}
#endif
os_close_on_exec(p[0], cmd, "pipe", "from");
+ if ((BINMODE & BINMODE_INPUT) != 0)
+ os_setbinmode(p[0], O_BINARY);
rp->iop = iop_alloc(p[0], cmd, 0);
find_input_parser(rp->iop);
iop_finish(rp->iop);
@@ -3403,7 +3488,9 @@ get_a_record(char **out, /* pointer to pointer to data */
recm.rt_start = iop->off + recm.len;
/* read more data, break if EOF */
+#ifndef min
#define min(x, y) (x < y ? x : y)
+#endif
/* subtract one in read count to leave room for sentinel */
room_left = iop->end - iop->dataend - 1;
amt_to_read = min(iop->readsize, room_left);
@@ -3741,21 +3828,38 @@ get_read_timeout(IOBUF *iop)
static ssize_t
read_with_timeout(int fd, char *buf, size_t size)
{
-#if ! defined(__MINGW32__) && ! defined(VMS)
+#if ! defined(VMS)
fd_set readfds;
struct timeval tv;
+#ifdef __MINGW32__
+ /*
+ * Only sockets can be read with a timeout. Also, the FD_*
+ * macros work on SOCKET type, not on int file descriptors.
+ */
+ SOCKET s = valid_socket(fd);
+
+ if (!s)
+ return read(fd, buf, size);
+#else
+ int s = fd;
+#endif
tv.tv_sec = read_timeout / 1000;
tv.tv_usec = 1000 * (read_timeout - 1000 * tv.tv_sec);
FD_ZERO(& readfds);
- FD_SET(fd, & readfds);
+ FD_SET(s, & readfds);
errno = 0;
+ /*
+ * Note: the 1st arg of 'select' is ignored on MS-Windows, so
+ * it's not a mistake to pass fd+1 there, although we use
+ * sockets, not file descriptors.
+ */
if (select(fd + 1, & readfds, NULL, NULL, & tv) < 0)
return -1;
- if (FD_ISSET(fd, & readfds))
+ if (FD_ISSET(s, & readfds))
return read(fd, buf, size);
/* else
timed out */
@@ -3767,9 +3871,9 @@ read_with_timeout(int fd, char *buf, size_t size)
errno = EAGAIN;
#endif
return -1;
-#else /* __MINGW32__ || VMS */
+#else /* VMS */
return read(fd, buf, size);
-#endif /* __MINGW32__ || VMS */
+#endif /* VMS */
}
/*
@@ -3805,9 +3909,18 @@ gawk_ferror(FILE *fp, void *opaque)
static int
gawk_fclose(FILE *fp, void *opaque)
{
+ int result;
+#ifdef __MINGW32__
+ SOCKET s = valid_socket (fileno(fp));
+#endif
(void) opaque;
- return fclose(fp);
+ result = fclose(fp);
+#ifdef __MINGW32__
+ if (s && closesocket(s) == SOCKET_ERROR)
+ result = -1;
+#endif
+ return result;
}
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 */
diff --git a/posix/ChangeLog b/posix/ChangeLog
index 67fdb42d..443951c3 100644
--- a/posix/ChangeLog
+++ b/posix/ChangeLog
@@ -1,3 +1,7 @@
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * gawkmisc.c (init_sockets): New dummy function.
+
2013-05-27 Arnold D. Robbins <arnold@skeeve.com>
* gawkmisc.c (optimal_bufsize): Change check from HAVE_ST_BLKSIZE
diff --git a/posix/gawkmisc.c b/posix/gawkmisc.c
index 90a41e4e..c90123d2 100644
--- a/posix/gawkmisc.c
+++ b/posix/gawkmisc.c
@@ -285,6 +285,13 @@ files_are_same(char *path, SRCFILE *src)
&& st.st_ino == src->sbuf.st_ino);
}
+#ifdef HAVE_SOCKETS
+void
+init_sockets(void)
+{
+}
+#endif
+
#ifdef __CYGWIN__
void
cygwin_premain0(int argc, char **argv, struct per_process *myself)
diff --git a/test/ChangeLog b/test/ChangeLog
index cb07ba4a..b5726c9d 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,15 @@
+2013-06-01 Eli Zaretskii <eliz@gnu.org>
+
+ * clos1way.awk: Don't use features of Posix shells, to allow this
+ test to work on Windows.
+
+ * 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.
+
+ * beginfile2.ok: Adapt to changes in beginfile2.sh.
+
2013-05-30 Arnold D. Robbins <arnold@skeeve.com>
* Makefile.am (profile4, profile5): New tests.
diff --git a/test/beginfile2.ok b/test/beginfile2.ok
index 2d872eae..fed71bb2 100644
--- a/test/beginfile2.ok
+++ b/test/beginfile2.ok
@@ -5,12 +5,12 @@ In BEGINFILE: beginfile2.in
--Test 1b--
In BEGIN
In BEGINFILE: beginfile2.in
-In BEGINFILE: /file/does/not/exist
-gawk: cmd. line:3: fatal: cannot open file `/file/does/not/exist' for reading (No such file or directory)
+In BEGINFILE: file/does/not/exist
+gawk: cmd. line:3: fatal: cannot open file `file/does/not/exist' for reading (No such file or directory)
--Test 2--
In BEGINFILE: beginfile2.in
In ENDFILE: beginfile2.in
-In BEGINFILE: /file/does/not/exist
+In BEGINFILE: file/does/not/exist
--Test 3--
In BEGINFILE: beginfile2.in
In ENDFILE: beginfile2.in
@@ -47,12 +47,12 @@ In ENDFILE: beginfile2.sh
beginfile2.in
1 2
--Test 9a--
-Skipping: 1:/file/does/not/exist
+Skipping: 1:file/does/not/exist
In BEGINFILE: 2:beginfile2.in
In Rule: beginfile2.in
In ENDFILE: beginfile2.in
--Test 9b--
-Skipping: 1:/file/does/not/exist
+Skipping: 1:file/does/not/exist
Skipping: 2:beginfile2.in
In ENDFILE: beginfile2.in
--Test 10--
diff --git a/test/beginfile2.sh b/test/beginfile2.sh
index 69161200..dffaa88b 100755
--- a/test/beginfile2.sh
+++ b/test/beginfile2.sh
@@ -13,70 +13,70 @@ then
fi
echo "--Test 1a--"
-prog=`$AWK '/#TEST1#/, /#TEST2#/' $AWKPROG`
+prog=`$AWK ' /#TEST1#/, /#TEST2#/' $AWKPROG`
$AWK "$prog" $AWKPROG
echo "--Test 1b--"
-$AWK "$prog" $AWKPROG /file/does/not/exist
+$AWK "$prog" $AWKPROG file/does/not/exist
echo "--Test 2--"
-prog=`$AWK '/#TEST2#/, /#TEST3#/' $AWKPROG`
-$AWK "$prog" $AWKPROG /file/does/not/exist
+prog=`$AWK ' /#TEST2#/, /#TEST3#/' $AWKPROG`
+$AWK "$prog" $AWKPROG file/does/not/exist
echo "--Test 3--"
-prog=`$AWK '/#TEST3#/, /#TEST4#/' $AWKPROG`
+prog=`$AWK ' /#TEST3#/, /#TEST4#/' $AWKPROG`
$AWK -vsrc=$SCRIPT "$prog" $AWKPROG
echo "--Test 4--"
-prog=`$AWK '/#TEST4#/, /#TEST5#/' $AWKPROG`
+prog=`$AWK ' /#TEST4#/, /#TEST5#/' $AWKPROG`
$AWK -vsrc=$SCRIPT "$prog" $AWKPROG
echo "--Test 5--"
-prog=`$AWK '/#TEST5#/, /#TEST6#/' $AWKPROG`
+prog=`$AWK ' /#TEST5#/, /#TEST6#/' $AWKPROG`
$AWK "$prog" $AWKPROG
echo "--Test 6--"
-prog=`$AWK '/#TEST6#/, /#TEST7#/' $AWKPROG`
+prog=`$AWK ' /#TEST6#/, /#TEST7#/' $AWKPROG`
$AWK "$prog" $AWKPROG
echo "--Test 7--"
-prog=`$AWK '/#TEST7#/, /#TEST8#/' $AWKPROG`
+prog=`$AWK ' /#TEST7#/, /#TEST8#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 8--"
-prog=`$AWK '/#TEST8#/, /#TEST9#/' $AWKPROG`
+prog=`$AWK ' /#TEST8#/, /#TEST9#/' $AWKPROG`
$AWK "$prog" $AWKPROG
echo "--Test 9a--"
-prog=`$AWK '/#TEST9#/, /#TEST10#/' $AWKPROG`
-$AWK "$prog" /file/does/not/exist $AWKPROG
+prog=`$AWK ' /#TEST9#/, /#TEST10#/' $AWKPROG`
+$AWK "$prog" file/does/not/exist $AWKPROG
echo "--Test 9b--"
-$AWK -vskip=1 "$prog" /file/does/not/exist $AWKPROG
+$AWK -vskip=1 "$prog" file/does/not/exist $AWKPROG
echo "--Test 10--"
-prog=`$AWK '/#TEST10#/, /#TEST11#/' $AWKPROG`
+prog=`$AWK ' /#TEST10#/, /#TEST11#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 11--"
-prog=`$AWK '/#TEST11#/, /#TEST12#/' $AWKPROG`
+prog=`$AWK ' /#TEST11#/, /#TEST12#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 12--"
-prog=`$AWK '/#TEST12#/, /#TEST13#/' $AWKPROG`
+prog=`$AWK ' /#TEST12#/, /#TEST13#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 13--"
-prog=`$AWK '/#TEST13#/, /#TEST14#/' $AWKPROG`
+prog=`$AWK ' /#TEST13#/, /#TEST14#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 14--"
-prog=`$AWK '/#TEST14#/, /#TEST15#/' $AWKPROG`
+prog=`$AWK ' /#TEST14#/, /#TEST15#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 15--"
-prog=`$AWK '/#TEST15#/, /#TEST16#/' $AWKPROG`
+prog=`$AWK ' /#TEST15#/, /#TEST16#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
echo "--Test 16--"
-prog=`$AWK '/#TEST16#/, /#TEST17#/' $AWKPROG`
+prog=`$AWK ' /#TEST16#/, /#TEST17#/' $AWKPROG`
$AWK "$prog" $AWKPROG $SCRIPT
diff --git a/test/clos1way.awk b/test/clos1way.awk
index 5bc40684..c9dab09a 100644
--- a/test/clos1way.awk
+++ b/test/clos1way.awk
@@ -1,5 +1,5 @@
BEGIN {
- command = "LC_ALL=C sort"
+ command = "sort"
n = split("abcdefghijklmnopqrstuvwxyz", a, "")
for (i = n; i > 0; i--) {