diff options
Diffstat (limited to 'win32/win32.c')
-rw-r--r-- | win32/win32.c | 192 |
1 files changed, 165 insertions, 27 deletions
diff --git a/win32/win32.c b/win32/win32.c index 46489c4e08..fd70242e9e 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -23,7 +23,7 @@ #include <windows.h> #include <winbase.h> #include <wincon.h> -#include "nt.h" +#include "win32.h" #include "dir.h" #ifndef index #define index(x, y) strchr((x), (y)) @@ -33,6 +33,8 @@ #define bool int #endif +#define TO_SOCKET(x) _get_osfhandle(x) + bool NtSyncProcess = TRUE; #if 0 // declared in header file extern char **environ; @@ -302,6 +304,14 @@ isInternalCmd(char *cmd) } +SOCKET +myget_osfhandle(int fh) +{ + return _get_osfhandle(fh); + +} + + FILE * mypopen (char *cmd, char *mode) { @@ -1582,40 +1592,101 @@ valid_filename(char *s) // if we can prevent perl from trying to do stdio on sockets. // +EXTERN_C int __cdecl _alloc_osfhnd(void); +EXTERN_C int __cdecl _set_osfhnd(int fh, long value); +EXTERN_C void __cdecl _lock_fhandle(int); +EXTERN_C void __cdecl _unlock_fhandle(int); +EXTERN_C void __cdecl _unlock(int); + +typedef struct { + long osfhnd; /* underlying OS file HANDLE */ + char osfile; /* attributes of file (e.g., open in text mode?) */ + char pipech; /* one char buffer for handles opened on pipes */ +#if defined (_MT) && !defined (DLL_FOR_WIN32S) + int lockinitflag; + CRITICAL_SECTION lock; +#endif /* defined (_MT) && !defined (DLL_FOR_WIN32S) */ +} ioinfo; + +EXTERN_C ioinfo * __pioinfo[]; + +#define IOINFO_L2E 5 +#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) +#define _pioinfo(i) (__pioinfo[i >> IOINFO_L2E] + (i & (IOINFO_ARRAY_ELTS - 1))) +#define _osfile(i) (_pioinfo(i)->osfile) + +#define FOPEN 0x01 /* file handle open */ +#define FAPPEND 0x20 /* file handle opened O_APPEND */ +#define FDEV 0x40 /* file handle refers to device */ +#define FTEXT 0x80 /* file handle is in text mode */ + +static int +my_open_osfhandle(long osfhandle, int flags) +{ + int fh; + char fileflags; /* _osfile flags */ + + /* copy relevant flags from second parameter */ + fileflags = FDEV; + + if (flags & O_APPEND) + fileflags |= FAPPEND; + + if (flags & O_TEXT) + fileflags |= FTEXT; + + /* attempt to allocate a C Runtime file handle */ + if ((fh = _alloc_osfhnd()) == -1) { + errno = EMFILE; /* too many open files */ + _doserrno = 0L; /* not an OS error */ + return -1; /* return error to caller */ + } + + /* the file is open. now, set the info in _osfhnd array */ + _set_osfhnd(fh, osfhandle); + + fileflags |= FOPEN; /* mark as open */ + + _osfile(fh) = fileflags; /* set osfile entry */ +// _unlock_fhandle(fh); + + return fh; /* return handle */ +} + FILE * myfdopen (int fd, const char *mode) { - FILE *fp; char sockbuf[80]; int optlen; int retval; + int fh; extern int errno; //fprintf(stderr, "myfdopen()\n"); + optlen = sizeof(sockbuf); retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); if (retval == SOCKET_ERROR) { int iRet; iRet = WSAGetLastError(); if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED) - return (_fdopen(fd, mode)); + return (_fdopen(fd, mode)); } // // If we get here, then fd is actually a socket. // - fp = xcalloc(sizeof(FILE), 1); -#if _MSC_VER < 800 - fileno(fp) = fd; -#else - fp->_file = fd; -#endif - if (*mode == 'r') - fp->_flag = _IOREAD; - else - fp->_flag = _IOWRT; - return fp; + + fh = my_open_osfhandle((SOCKET)fd, O_RDWR|O_BINARY); + return _fdopen(fh, mode); // return file pointer +} + + +void +myfdclose(FILE *fp) +{ + fclose(fp); } @@ -1709,6 +1780,36 @@ ioctl(int i, unsigned int u, long data) } +#undef FD_SET + +void +myfdset(int fd, fd_set *set) +{ + unsigned int i; + SOCKET s = TO_SOCKET(fd); + + for (i = 0; i < set->fd_count; i++) { + if (set->fd_array[i] == s) { + return; + } + } + if (i == set->fd_count) { + if (set->fd_count < FD_SETSIZE) { + set->fd_array[i] = s; + set->fd_count++; + } + } +} + + +#undef FD_ISSET + +int +myfdisset(int fd, fd_set *set) +{ + return __WSAFDIsSet(TO_SOCKET(fd), set); +} + // // Networking trampolines // These are used to avoid socket startup/shutdown overhead in case @@ -1737,6 +1838,7 @@ StartSockets () { WORD version; WSADATA retdata; int ret; + int iSockOpt; // // initalize the winsock interface and insure that it\'s @@ -1752,6 +1854,13 @@ StartSockets () { rb_fatal("could not find version 1 of winsock dll\n"); atexit((void (*)(void)) WSACleanup); + + iSockOpt = SO_SYNCHRONOUS_NONALERT; + /* + * Enable the use of sockets as filehandles + */ + setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, + (char *)&iSockOpt, sizeof(iSockOpt)); } #undef accept @@ -1764,7 +1873,7 @@ myaccept (SOCKET s, struct sockaddr *addr, int *addrlen) if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = accept (s, addr, addrlen)) == INVALID_SOCKET) + if ((r = accept (TO_SOCKET(s), addr, addrlen)) == INVALID_SOCKET) errno = WSAGetLastError(); return r; } @@ -1808,7 +1917,7 @@ mygetpeername (SOCKET s, struct sockaddr *addr, int *addrlen) if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = getpeername (s, addr, addrlen)) == SOCKET_ERROR) + if ((r = getpeername (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -1822,7 +1931,7 @@ mygetsockname (SOCKET s, struct sockaddr *addr, int *addrlen) if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = getsockname (s, addr, addrlen)) == SOCKET_ERROR) + if ((r = getsockname (TO_SOCKET(s), addr, addrlen)) == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -1850,7 +1959,7 @@ myioctlsocket (SOCKET s, long cmd, u_long *argp) if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = ioctlsocket (s, cmd, argp)) == SOCKET_ERROR) + if ((r = ioctlsocket (TO_SOCKET(s), cmd, argp)) == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -1878,7 +1987,7 @@ myrecv (SOCKET s, char *buf, int len, int flags) if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = recv (s, buf, len, flags)) == SOCKET_ERROR) + if ((r = recv (TO_SOCKET(s), buf, len, flags)) == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -1893,7 +2002,7 @@ myrecvfrom (SOCKET s, char *buf, int len, int flags, if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = recvfrom (s, buf, len, flags, from, fromlen)) == SOCKET_ERROR) + if ((r = recvfrom (TO_SOCKET(s), buf, len, flags, from, fromlen)) == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -1907,7 +2016,7 @@ mysend (SOCKET s, char *buf, int len, int flags) if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = send (s, buf, len, flags)) == SOCKET_ERROR) + if ((r = send (TO_SOCKET(s), buf, len, flags)) == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -1922,7 +2031,7 @@ mysendto (SOCKET s, char *buf, int len, int flags, if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = sendto (s, buf, len, flags, to, tolen)) == SOCKET_ERROR) + if ((r = sendto (TO_SOCKET(s), buf, len, flags, to, tolen)) == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -1936,7 +2045,8 @@ mysetsockopt (SOCKET s, int level, int optname, char *optval, int optlen) if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = setsockopt (s, level, optname, optval, optlen)) == SOCKET_ERROR) + if ((r = setsockopt (s, level, optname, optval, optlen)) + == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -1950,7 +2060,7 @@ myshutdown (SOCKET s, int how) if (!NtSocketsInitialized++) { StartSockets(); } - if ((r = shutdown (s, how)) == SOCKET_ERROR) + if ((r = shutdown (TO_SOCKET(s), how)) == SOCKET_ERROR) errno = WSAGetLastError(); return r; } @@ -2120,7 +2230,7 @@ waitpid (pid_t pid, int *stat_loc, int options) #include <sys/timeb.h> -void _cdecl +int _cdecl gettimeofday(struct timeval *tv, struct timezone *tz) { struct timeb tb; @@ -2128,6 +2238,8 @@ gettimeofday(struct timeval *tv, struct timezone *tz) ftime(&tb); tv->tv_sec = tb.time; tv->tv_usec = tb.millitm * 1000; + + return 0; } char * @@ -2170,16 +2282,17 @@ str_grow(struct RString *str, size_t new_size) } int -chown(char *path, int owner, int group) +chown(const char *path, int owner, int group) { return 0; } +#include <signal.h> int kill(int pid, int sig) { #if 1 - if (pid == GetCurrentProcessId()) + if ((unsigned int)pid == GetCurrentProcessId()) return raise(sig); if (sig == 2 && pid > 0) @@ -2204,3 +2317,28 @@ wait() return 0; } +char * +win32_getenv(const char *name) +{ + static char *curitem = NULL; /* XXX threadead */ + static DWORD curlen = 0; /* XXX threadead */ + DWORD needlen; + if (!curitem) { + curlen = 512; + curitem = ALLOC_N(char, curlen); + } + + needlen = GetEnvironmentVariable(name,curitem,curlen); + if (needlen != 0) { + while (needlen > curlen) { + REALLOC_N(curitem, char, needlen); + curlen = needlen; + needlen = GetEnvironmentVariable(name, curitem, curlen); + } + } + else { + return NULL; + } + + return curitem; +} |