summaryrefslogtreecommitdiff
path: root/pc/gawkmisc.pc
diff options
context:
space:
mode:
Diffstat (limited to 'pc/gawkmisc.pc')
-rw-r--r--pc/gawkmisc.pc316
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__ */