diff options
Diffstat (limited to 'pc/gawkmisc.pc')
-rw-r--r-- | pc/gawkmisc.pc | 316 |
1 files changed, 310 insertions, 6 deletions
diff --git a/pc/gawkmisc.pc b/pc/gawkmisc.pc index 64b42396..fdd32e7e 100644 --- a/pc/gawkmisc.pc +++ b/pc/gawkmisc.pc @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 1986, 1988, 1989, 1991 - 2003 the Free Software Foundation, Inc. + * Copyright (C) 1986, 1988, 1989, 1991 - 2003, 2012 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. @@ -31,6 +31,8 @@ char *defpath = DEFPATH; # else char *defpath = ".;c:\\lib\\awk;c:\\gnu\\lib\\awk"; # endif +/* the Makefile should define DEFLIBPATH */ +char *deflibpath = DEFLIBPATH; #ifdef __EMX__ #include<io.h> @@ -40,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 * @@ -203,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 } @@ -230,6 +254,31 @@ int fd; return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)); } +/* os_isreadable --- fd can be read from */ + +int +os_isreadable(const awk_input_buf_t *iobuf, bool *isdir) +{ + *isdir = false; + + switch (iobuf->sbuf.st_mode & S_IFMT) { + case S_IFREG: + case S_IFCHR: /* ttys, /dev/null, .. */ +#ifdef S_IFSOCK + case S_IFSOCK: +#endif +#ifdef S_IFIFO + case S_IFIFO: +#endif + return true; + case S_IFDIR: + *isdir = true; + /* fall through */ + default: + return false; + } +} + /* os_is_setuid --- true if running setuid root */ int @@ -535,8 +584,6 @@ unsetenv (const char *name) return setenv (name, "", 1); } -#include <windows.h> - int usleep(unsigned int usec) { @@ -569,8 +616,257 @@ wctob (wint_t wc) return EOF; } +/* + * On MS-Windows with MinGW, execvp causes the shell and the re-exec'ed + * dgawk to compete for the keyboard input. + * + * This will need work if we ever need a real version of execvp. + */ +int execvp(const char *file, const char *const *argv) +{ + if (_spawnvp(_P_WAIT, file, (const char * const *)argv) != -1) + exit(EXIT_SUCCESS); + + return -1; +} + +#ifdef DYNAMIC + +#include <dlfcn.h> + +static DWORD last_err; + +void * +dlopen (const char *file, int mode) +{ + char dllfn[MAX_PATH], *p; + HANDLE dllhandle; + + if (mode != RTLD_LAZY) + { + errno = EINVAL; + last_err = ERROR_INVALID_PARAMETER; + return NULL; + } + + /* MSDN says to be sure to use backslashes in the DLL file name. */ + strcpy (dllfn, file); + for (p = dllfn; *p; p++) + if (*p == '/') + *p = '\\'; + + dllhandle = LoadLibrary (dllfn); + if (!dllhandle) + last_err = GetLastError (); + + return dllhandle; +} + +char * +dlerror (void) +{ + static char errbuf[1024]; + DWORD ret; + + if (!last_err) + return NULL; + + ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM + | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, last_err, 0, errbuf, sizeof (errbuf), NULL); + while (ret > 0 && (errbuf[ret - 1] == '\n' || errbuf[ret - 1] == '\r')) + --ret; + + errbuf[ret] = '\0'; + if (!ret) + sprintf (errbuf, "Error code %lu", last_err); + + last_err = 0; + return errbuf; +} + +int +dlclose (void *handle) +{ + if (!handle || handle == INVALID_HANDLE_VALUE) + return -1; + if (!FreeLibrary (handle)) + return -1; + + return 0; +} + +void * +dlsym (void *handle, const char *name) +{ + FARPROC addr = NULL; + + if (!handle || handle == INVALID_HANDLE_VALUE) + { + last_err = ERROR_INVALID_PARAMETER; + return NULL; + } + + addr = GetProcAddress (handle, name); + if (!addr) + last_err = GetLastError (); + + return (void *)addr; +} +#endif /* DYNAMIC */ + +#ifdef HAVE_SOCKETS +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__ */ +#if defined(__DJGPP__) || defined(__MINGW32__) || defined(__EMX__) + +void +init_sockets(void) +{ +#if defined(HAVE_SOCKETS) && !defined(__EMX__) + WSADATA winsockData; + int errcode; + + if ((errcode = WSAStartup (0x101, &winsockData)) != 0 + || winsockData.wVersion != 0x101) + fatal(_("cannot start Winsock (%d)"), errcode); +#endif +} + +#endif /* __DJGPP__ || __MINGW32__ */ + #ifdef __DJGPP__ int @@ -582,4 +878,12 @@ unsetenv (const char *name) return putenv (name); } +/* This is needed to defeat too-clever GCC warnings in dfa.c about + comparison being always false due to limited range of data type. */ +wint_t +btowc (int c) +{ + return c; +} + #endif /* __DJGPP__ */ |