diff options
author | Eli Zaretskii <eliz@gnu.org> | 2013-06-01 13:03:29 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2013-06-01 13:03:29 +0300 |
commit | 5482bf19246965d6839fe9df1aec0785f0b1a329 (patch) | |
tree | 818777446f62f531462f2b64b70d9868bcdcaa95 | |
parent | a25b9b39ac2c49b822328414240061f6d22ddef2 (diff) | |
download | gawk-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-- | ChangeLog | 33 | ||||
-rw-r--r-- | extension/ChangeLog | 11 | ||||
-rw-r--r-- | extension/filefuncs.c | 1 | ||||
-rw-r--r-- | extension/readdir.c | 1 | ||||
-rw-r--r-- | extension/time.c | 1 | ||||
-rw-r--r-- | getopt.c | 3 | ||||
-rw-r--r-- | io.c | 177 | ||||
-rw-r--r-- | pc/ChangeLog | 42 | ||||
-rw-r--r-- | pc/Makefile | 14 | ||||
-rw-r--r-- | pc/Makefile.tst | 18 | ||||
-rw-r--r-- | pc/config.h | 12 | ||||
-rw-r--r-- | pc/config.sed | 12 | ||||
-rw-r--r-- | pc/gawkmisc.pc | 177 | ||||
-rw-r--r-- | pc/in.h | 1 | ||||
-rw-r--r-- | pc/popen.c | 72 | ||||
-rw-r--r-- | pc/popen.h | 5 | ||||
-rw-r--r-- | pc/socket.h | 42 | ||||
-rw-r--r-- | posix/ChangeLog | 4 | ||||
-rw-r--r-- | posix/gawkmisc.c | 7 | ||||
-rw-r--r-- | test/ChangeLog | 12 | ||||
-rw-r--r-- | test/beginfile2.ok | 10 | ||||
-rwxr-xr-x | test/beginfile2.sh | 40 | ||||
-rw-r--r-- | test/clos1way.awk | 2 |
23 files changed, 613 insertions, 84 deletions
@@ -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 @@ -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> @@ -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. */ @@ -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; @@ -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--) { |