You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by mt...@apache.org on 2011/05/03 09:26:38 UTC

svn commit: r1098947 - in /commons/sandbox/runtime/trunk/src/main/native: include/acr/stdinc.h os/win32/arch_defs.h os/win32/arch_opts.h os/win32/posix.c os/win32/util.c os/win32/winapi.c

Author: mturk
Date: Tue May  3 07:26:38 2011
New Revision: 1098947

URL: http://svn.apache.org/viewvc?rev=1098947&view=rev
Log:
Add more win32 utils

Modified:
    commons/sandbox/runtime/trunk/src/main/native/include/acr/stdinc.h
    commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_defs.h
    commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h
    commons/sandbox/runtime/trunk/src/main/native/os/win32/posix.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c

Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/stdinc.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/stdinc.h?rev=1098947&r1=1098946&r2=1098947&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/stdinc.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/stdinc.h Tue May  3 07:26:38 2011
@@ -28,7 +28,7 @@
 #  define WIN32_LEAN_AND_MEAN
 # endif
 # if !defined(_WIN32_WINNT)
-#  define _WIN32_WINNT 0x0501
+#  define _WIN32_WINNT 0x0502
 # endif
 
 /* Ignore most warnings (back down to /W3) for poorly constructed headers
@@ -79,6 +79,7 @@
 # include <mswsock.h>
 # include <ws2tcpip.h>
 # include <wincrypt.h>
+# include <winioctl.h>
 #endif /* WIN32 */
 
 /* GNU libc requires __STDC_LIMIT_MACROS

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_defs.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_defs.h?rev=1098947&r1=1098946&r2=1098947&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_defs.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_defs.h Tue May  3 07:26:38 2011
@@ -86,13 +86,6 @@ typedef struct OVERLAPPED_VBUFF {
     } else (void)0
 
 
-#define WAIT_OBJECT_SIGNAL      WAIT_OBJECT_0
-#define WAIT_OBJECT_SIGPIPE    (WAIT_OBJECT_0 + 1)
-#define WAIT_OBJECT_1          (WAIT_OBJECT_0 + 1)
-#define WAIT_OBJECT_2          (WAIT_OBJECT_0 + 2)
-#define WAIT_OBJECT_3          (WAIT_OBJECT_0 + 3)
-#define WAIT_OBJECT_4          (WAIT_OBJECT_0 + 4)
-
 /*
  * ---------------------------------------------------------------------
  * begin of DDK declarations
@@ -161,12 +154,11 @@ static __inline int isblank(int c)
     return c == ' ' || c == '\t';
 }
 
-#define WAIT_OBJECT_SIGNAL      WAIT_OBJECT_0
-#define WAIT_OBJECT_SIGPIPE    (WAIT_OBJECT_0 + 1)
 #define WAIT_OBJECT_1          (WAIT_OBJECT_0 + 1)
 #define WAIT_OBJECT_2          (WAIT_OBJECT_0 + 2)
 #define WAIT_OBJECT_3          (WAIT_OBJECT_0 + 3)
 #define WAIT_OBJECT_4          (WAIT_OBJECT_0 + 4)
+#define WAIT_OBJECT_M          (WAIT_OBJECT_0 + MAXIMUM_WAIT_OBJECTS)
 
 /**
  * Definitions matching the KeyAccessRights Java enum

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h?rev=1098947&r1=1098946&r2=1098947&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/arch_opts.h Tue May  3 07:26:38 2011
@@ -145,6 +145,39 @@ ACR_DECLARE_LATE_DLL_FUNC1(SYSDLL_KERNEL
     (lpSymlinkFileName, lpTargetFileName, dwFlags));
 #define CreateSymbolicLinkW _delayload_CreateSymbolicLinkW
 
+#if !defined(POLLERR)
+/* Event flag definitions for WSAPoll(). */
+#define POLLRDNORM  0x0100
+#define POLLRDBAND  0x0200
+#define POLLIN      (POLLRDNORM | POLLRDBAND)
+#define POLLPRI     0x0400
+
+#define POLLWRNORM  0x0010
+#define POLLOUT     (POLLWRNORM)
+#define POLLWRBAND  0x0020
+
+#define POLLERR     0x0001
+#define POLLHUP     0x0002
+#define POLLNVAL    0x0004
+
+typedef struct pollfd {
+    SOCKET  fd;
+    SHORT   events;
+    SHORT   revents;
+
+} WSAPOLLFD, *PWSAPOLLFD, FAR *LPWSAPOLLFD;
+
+#endif /* !defined(POLLERR) */
+#ifdef WSAPoll
+#undef WSAPoll
+#endif
+ACR_DECLARE_LATE_DLL_FUNC1(SYSDLL_WS2_32, int, -1,
+                           WSAAPI, WSAPoll, 0, (
+    IN OUT LPWSAPOLLFD fdArray,
+    IN ULONG fds,
+    IN INT timeout),
+    (fdArray, fds, timeout));
+#define WSAPoll _delayload_WSAPoll
 
 extern HANDLE acr_raised_event;
 extern volatile LONG acr_signal_waiters;
@@ -235,10 +268,14 @@ ACR_INLINE(void) MsecTimeToFileTime(LPFI
 
 HANDLE  AcrNullPipe(int flags, int fd);
 int     AcrPipePair(HANDLE *rd, HANDLE *wr, int flags, char *name);
+int     AcrSocketPair(SOCKET *rd, SOCKET *wr, int nonblocking);
+int     AcrDrainSocket(SOCKET sd);
 int     AcrNonblock(int sd, int on);
 size_t  wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz);
 size_t  wcslcat(wchar_t *dst, const wchar_t *src, size_t siz);
 const wchar_t *basename_w(const wchar_t *path);
 wchar_t       *dirname_w(const wchar_t *path, wchar_t *dname, size_t dlen);
+int            symlink_w(const wchar_t *target, const wchar_t *lnkname);
+ssize_t        readlink_w(const wchar_t *lnkname, wchar_t *buf, size_t len);
 
 #endif /* _ACR_ARCH_OPTS_H_ */

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/posix.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/posix.c?rev=1098947&r1=1098946&r2=1098947&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/posix.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/posix.c Tue May  3 07:26:38 2011
@@ -160,3 +160,212 @@ wcslcat(wchar_t *dst, const wchar_t *src
 
     return(dlen + (s - src));   /* count does not include NUL */
 }
+
+int
+symlink_w(const wchar_t *target, const wchar_t *lnkname)
+{
+    int    rc  = 0;
+    char  *mpb = 0;
+    DWORD  dwFlags = 0;
+    DWORD  dwAttrs;
+    size_t tlen = wcslen(target);
+
+    dwAttrs = GetFileAttributesW(target);
+    if (dwAttrs == INVALID_FILE_ATTRIBUTES)
+        return -1;
+    if (dwAttrs & FILE_ATTRIBUTE_DIRECTORY)
+        dwFlags = SYMBOLIC_LINK_FLAG_DIRECTORY;
+
+    if (ACR_HAVE_LATE_DLL_FUNC(CreateSymbolicLinkW)) {
+        if (CreateSymbolicLinkW(lnkname, target, dwFlags))
+            return 0;
+        else
+            return -1;
+    }
+    /* Pre Vista. Let's do it the hard way...
+     * Note that this only works for linking directories.
+     */
+    if (dwFlags ==  SYMBOLIC_LINK_FLAG_DIRECTORY) {
+        HANDLE token = 0;
+        HANDLE hlink = INVALID_HANDLE_VALUE;
+        PREPARSE_DATA_BUFFER rdb;
+        DWORD  dlen;
+        size_t blen = (MAXIMUM_REPARSE_DATA_BUFFER_SIZE - sizeof(PREPARSE_DATA_BUFFER)) / sizeof(wchar_t);
+
+        mpb = calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
+        if (mpb == 0) {
+            goto cleanup;
+        }
+        /* Remove the link directory if already exists */
+        RemoveDirectoryW(lnkname);
+        if (!CreateDirectoryW(lnkname, 0)) {
+            /* Failed to create link name directory */
+            rc = ACR_GET_OS_ERROR();
+            goto cleanup;
+        }
+        if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) {
+            TOKEN_PRIVILEGES tp;
+            if (LookupPrivilegeValue(0, SE_RESTORE_NAME, &tp.Privileges[0].Luid)) {
+                tp.PrivilegeCount = 1;
+                tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+                AdjustTokenPrivileges(token, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
+                                      0, 0);
+            }
+            CloseHandle(token);
+        }
+        hlink = CreateFileW(lnkname,
+                            GENERIC_WRITE,
+                            0,
+                            0,
+                            OPEN_EXISTING,
+                            FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
+                            0);
+        if (hlink == INVALID_HANDLE_VALUE) {
+            rc = ACR_GET_OS_ERROR();
+            goto cleanup;
+        }
+        rdb = (PREPARSE_DATA_BUFFER)mpb;
+        rdb->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
+        wcslcpy(rdb->MountPointReparseBuffer.PathBuffer, L"\\??\\", blen);
+        wcslcat(rdb->MountPointReparseBuffer.PathBuffer, target, blen);
+        tlen = wcslen(rdb->MountPointReparseBuffer.PathBuffer);
+
+        rdb->MountPointReparseBuffer.SubstituteNameLength = (USHORT)(tlen  * sizeof(wchar_t));
+        rdb->MountPointReparseBuffer.PrintNameOffset = (USHORT)((tlen + 1) * sizeof(wchar_t));
+        rdb->ReparseDataLength = (USHORT)(sizeof(rdb->MountPointReparseBuffer) + ((tlen + 1) * sizeof(wchar_t)));
+
+        if (!DeviceIoControl(hlink, FSCTL_SET_REPARSE_POINT,
+                             rdb, rdb->ReparseDataLength + 8,
+                             0, 0, &dlen, 0)) {
+            rc = ACR_GET_OS_ERROR();
+        }
+        CloseHandle(hlink);
+    }
+    else {
+        /* XXX: How to figure out the target of the hard link? */
+        if (!CreateHardLinkW(lnkname, target, 0))
+            rc = ACR_GET_OS_ERROR();
+    }
+
+cleanup:
+    AcrFree(mpb);
+    if (rc != 0) {
+        ACR_SET_OS_ERROR(rc);
+        return -1;
+    }
+    else
+        return 0;
+}
+
+ssize_t
+readlink_w(const wchar_t *lnkname, wchar_t *buf, size_t len)
+{
+    int rc = 0;
+    char    *mpb;
+    char    *pb;
+    wchar_t *pname;
+    wchar_t *sname;
+    size_t   noff;
+    size_t   nlen;
+    size_t   soff;
+    size_t   slen;
+    int      isabs = 0;
+    int      isvol = 0;
+    ssize_t  rv = (ssize_t)-1;
+    HANDLE  sh;
+    DWORD   dl;
+    PREPARSE_DATA_BUFFER repb;
+
+    sh = CreateFileW(lnkname,
+                     GENERIC_READ,
+                     FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                     0,
+                     OPEN_EXISTING,
+                     FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
+                     0);
+    if (sh == INVALID_HANDLE_VALUE)
+        return rv;
+    mpb = calloc(1, MAXIMUM_REPARSE_DATA_BUFFER_SIZE + 64);
+    if (mpb == 0) {
+        CloseHandle(sh);
+        ACR_SET_OS_ERROR(ACR_ENOMEM);
+        return rv;
+    }
+    if (!DeviceIoControl(sh,
+                         FSCTL_GET_REPARSE_POINT,
+                         0,
+                         0,
+                         mpb,
+                         MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
+                         &dl,
+                         0)) {
+        int es = ACR_GET_OS_ERROR();
+        CloseHandle(sh);
+        AcrFree(mpb);
+        ACR_SET_OS_ERROR(es);
+        return rv;
+    }
+    CloseHandle(sh);
+    repb = (PREPARSE_DATA_BUFFER)mpb;
+    switch (repb->ReparseTag) {
+        case IO_REPARSE_TAG_MOUNT_POINT:
+            isabs = 1;
+            pb    = (char *)repb->MountPointReparseBuffer.PathBuffer;
+            nlen  = repb->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
+            noff  = repb->MountPointReparseBuffer.PrintNameOffset;
+            pname = (wchar_t *)(pb + noff);
+            slen  = repb->MountPointReparseBuffer.SubstituteNameLength;
+            soff  = repb->MountPointReparseBuffer.SubstituteNameOffset;
+            sname = (wchar_t *)(pb + soff);
+        break;
+        case IO_REPARSE_TAG_SYMLINK:
+            isabs = repb->SymbolicLinkReparseBuffer.Flags == 0 ? 1 : 0;
+            pb    = (char *)repb->SymbolicLinkReparseBuffer.PathBuffer;
+            noff  = repb->SymbolicLinkReparseBuffer.PrintNameOffset;
+            nlen  = repb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
+            pname = (wchar_t *)(pb + noff);
+            slen = repb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
+            soff = repb->SymbolicLinkReparseBuffer.SubstituteNameOffset;
+            sname = (wchar_t *)(pb + soff);
+        break;
+        default:
+            rc = ACR_EBADF;
+        break;
+    }
+    if (rc == 0) {
+        sname[slen] = L'\0';
+#if 0
+        printf("\nSymlink    : '%S'\n", lnkname);
+        printf("print name : '%S'\n", pname);
+        printf("substitute : '%S'\n", sname);
+#endif
+        if (isabs && slen > 4 && *sname == L'\\') {
+            if (wcsncmp(sname, L"\\??\\UNC\\", 8) == 0) {
+                sname += 6;
+                *sname = L'\\';
+            }
+            else if (wcsncmp(sname, L"\\??\\", 4) == 0 ||
+                     wcsncmp(sname, L"\\\\?\\", 4) == 0) {
+                sname += 4;
+                if (wcsncmp(sname, L"Volume{", 7) == 0)
+                    isvol = 1;
+            }
+        }
+        if (isvol == 0) {
+            rv = wcslcpy(buf, sname, len);
+        }
+        else {
+            /* XXX: What to do with Volume mount points ?
+             */
+            printf("volume     : '%S'\n", sname);
+            rv = wcslcpy(buf, sname, len);
+        }
+#if 0
+        printf("resolved   : '%S'\n", buf);
+        fflush(stdout);
+#endif
+    }
+    AcrFree(mpb);
+    ACR_SET_ERRNO_IF(rc);
+    return rv;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c?rev=1098947&r1=1098946&r2=1098947&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/util.c Tue May  3 07:26:38 2011
@@ -67,7 +67,7 @@ AcrGetLateDLL(SYSDLL_TOKEN libidx)
 }
 
 FARPROC
- AcrGetLateDLLAddress(SYSDLL_TOKEN libidx, const char *name, int undec)
+AcrGetLateDLLAddress(SYSDLL_TOKEN libidx, const char *name, int undec)
 {
     int rc = 0;
     FARPROC fp = 0;
@@ -331,3 +331,164 @@ AcrNonblock(int sd, int on)
     else
         return 0;
 }
+
+int
+AcrSocketPair(SOCKET *rd, SOCKET *wr, int nonblocking)
+{
+    FD_SET rs;
+    SOCKET ls;
+    struct timeval socktm;
+    struct sockaddr_in pa;
+    struct sockaddr_in la;
+    struct sockaddr_in ca;
+    int nrd;
+    int rv = 0;
+    int ll = ISIZEOF(la);
+    int cl = ISIZEOF(ca);
+    int bm = 1;
+    int uid[2];
+    int iid[2];
+
+    *rd = INVALID_SOCKET;
+    *wr = INVALID_SOCKET;
+
+    /* Create the unique socket identifier
+     * so that we know the connection originated
+     * from us.
+     */
+    uid[0] = GetCurrentProcessId() + GetCurrentThreadId();
+    uid[1] = InterlockedIncrement(&_pipe_id);
+    if ((ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+        return ACR_GET_NETOS_ERROR();
+    }
+
+    pa.sin_family = AF_INET;
+    pa.sin_port   = 0;
+    pa.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+    if (bind(ls, (SOCKADDR *)&pa, ISIZEOF(pa)) == SOCKET_ERROR) {
+        rv =  ACR_GET_NETOS_ERROR();
+        goto cleanup;
+    }
+    if (getsockname(ls, (SOCKADDR *)&la, &ll) == SOCKET_ERROR) {
+        rv =  ACR_GET_NETOS_ERROR();
+        goto cleanup;
+    }
+    if (listen(ls, 1) == SOCKET_ERROR) {
+        rv =  ACR_GET_NETOS_ERROR();
+        goto cleanup;
+    }
+    if ((*wr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
+        rv = ACR_GET_NETOS_ERROR();
+        goto cleanup;
+    }
+    if (connect(*wr, (SOCKADDR *)&la, ISIZEOF(la)) == SOCKET_ERROR) {
+        rv =  ACR_GET_NETOS_ERROR();
+        goto cleanup;
+    }
+    if (send(*wr, (char *)uid, ISIZEOF(uid), 0) != ISIZEOF(uid)) {
+        if ((rv =  ACR_GET_NETOS_ERROR()) == 0) {
+            rv = ACR_EINCOMPLETE;
+        }
+        goto cleanup;
+    }
+    if (ioctlsocket(ls, FIONBIO, &bm) == SOCKET_ERROR) {
+        rv = ACR_GET_NETOS_ERROR();
+        goto cleanup;
+    }
+    for (;;) {
+        int ns;
+        /* Listening socket is nonblocking by now.
+         * The accept should create the socket
+         * immediatelly because we are connected already.
+         * However on buys systems this can take a while
+         * until winsock gets a chance to handle the events.
+         */
+        FD_ZERO(&rs);
+        FD_SET(ls, &rs);
+
+        socktm.tv_sec  = 1;
+        socktm.tv_usec = 0;
+        if ((ns = select(0, &rs, NULL, NULL, &socktm)) == SOCKET_ERROR) {
+            /* Accept still not signaled */
+            Sleep(100);
+            continue;
+        }
+        if (ns == 0) {
+            /* No connections in the last second */
+            continue;
+        }
+        if ((*rd = accept(ls, (SOCKADDR *)&ca, &cl)) == INVALID_SOCKET) {
+            rv =  ACR_GET_NETOS_ERROR();
+            goto cleanup;
+        }
+        /* Verify the connection by reading the send identification.
+         */
+        nrd = recv(*rd, (char *)iid, ISIZEOF(iid), 0);
+        if (nrd == ISIZEOF(iid)) {
+            if (memcmp(uid, iid, sizeof(uid)) == 0) {
+                /* Wow, we recived what we send.
+                 */
+                break;
+            }
+        }
+        else if (nrd == SOCKET_ERROR) {
+            rv =  ACR_GET_NETOS_ERROR();
+            goto cleanup;
+        }
+        closesocket(*rd);
+    }
+    if (nonblocking) {
+        /* Put the write side to the nonblocking mode
+         * if nonblocking mode was requested
+         */
+        bm = 1;
+        if (ioctlsocket(*wr, FIONBIO, &bm) == SOCKET_ERROR) {
+            rv = ACR_GET_NETOS_ERROR();
+            goto cleanup;
+        }
+    }
+    else {
+        /* Put the read side back to the blocking mode
+         */
+        bm = 0;
+        if (ioctlsocket(*rd, FIONBIO, &bm) == SOCKET_ERROR) {
+            rv = ACR_GET_NETOS_ERROR();
+            goto cleanup;
+        }
+    }
+    /* We don't need the listening socket any more
+     */
+    closesocket(ls);
+    return 0;
+
+cleanup:
+    /* Don't leak resources on failure
+     */
+    if (*rd != INVALID_SOCKET)
+        closesocket(*rd);
+    if (*wr != INVALID_SOCKET)
+        closesocket(*wr);
+
+    *rd = INVALID_SOCKET;
+    *wr = INVALID_SOCKET;
+    closesocket(ls);
+    return rv;
+}
+
+int
+AcrDrainSocket(SOCKET sd)
+{
+    char rb[512];
+    int  nr = ISIZEOF(rb);
+    int  rd;
+
+    while ((rd = recv(sd, rb, nr, 0)) != SOCKET_ERROR) {
+        if (rd != nr)
+            break;
+    }
+    if (rd == SOCKET_ERROR)
+        return ACR_GET_NETOS_ERROR();
+    else
+        return 0;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c?rev=1098947&r1=1098946&r2=1098947&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/winapi.c Tue May  3 07:26:38 2011
@@ -21,7 +21,7 @@
 #include "acr/port.h"
 #include "acr/clazz.h"
 #include "acr/misc.h"
-#include "arch_defs.h"
+#include "arch_opts.h"
 
 #include <sddl.h>