commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mt...@apache.org
Subject svn commit: r802434 - in /commons/sandbox/runtime/trunk/src/main/native: Makefile.msc.in include/arch/windows/acr_arch.h os/win32/dirent.c os/win32/wutil.c
Date Sat, 08 Aug 2009 18:48:05 GMT
Author: mturk
Date: Sat Aug  8 18:48:04 2009
New Revision: 802434

URL: http://svn.apache.org/viewvc?rev=802434&view=rev
Log:
Add win32 posix dirent

Added:
    commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c   (with props)
Modified:
    commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
    commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
    commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=802434&r1=802433&r2=802434&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Sat Aug  8 18:48:04 2009
@@ -92,6 +92,7 @@
 	$(SRCDIR)/modules/network/ssl/openssl.$(OBJ)
 
 WINDOWS_OBJS= \
+	$(SRCDIR)/os/win32/dirent.$(OBJ) \
 	$(SRCDIR)/os/win32/execmem.$(OBJ) \
 	$(SRCDIR)/os/win32/file.$(OBJ) \
 	$(SRCDIR)/os/win32/main.$(OBJ) \

Modified: commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h?rev=802434&r1=802433&r2=802434&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h Sat Aug
 8 18:48:04 2009
@@ -335,7 +335,35 @@
     return;
 }
 
+/**
+ * Utility functions
+ */
 wchar_t *res_name_from_filenamew(int, wchar_t *, const wchar_t *);
+int utf8_to_unicode_path(wchar_t *, size_t, const char *, size_t);
+int unicode_to_utf8_path(char *, size_t, const wchar_t *);
+
+
+struct dirent {
+    ino_t            d_ino;        /* inode number */
+    off_t            d_off;        /* offset to the next dirent */
+    unsigned short   d_reclen;     /* length of this record (name) */
+    unsigned char    d_type;       /* unused */
+    char             d_name[1024]; /* extended from MAX_PATH
+                                    * file name is UTF-8 encoded
+                                    */
+};
+
+typedef struct DIR {
+    HANDLE           d_find;       /* Handle to FindFirstFile */
+    off_t            d_stat;       /* Status of search
+                                    *  0 -> Not started yet
+                                    * -1 -> EOF
+                                    * >0 -> o based index of next entry.
+                                    */
+
+    struct dirent    d_dir;
+    wchar_t          d_name[8192];
+} DIR;
 
 /*
  * ---------------------------------------------------------------------

Added: commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c?rev=802434&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c Sat Aug  8 18:48:04 2009
@@ -0,0 +1,236 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * dirent.c
+ *
+ * Derived from DIRLIB.C by Matt J. Weinstein
+ * This note appears in the DIRLIB.H
+ * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
+ *
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+#include "acr_memory.h"
+#include "acr_error.h"
+
+DIR *opendir(const char *path)
+{
+    DIR *dir;
+    DWORD rc;
+    size_t  len;
+    wchar_t wpath[ACR_HBUFF_SIZ];   /* Limited to 8K paths */
+
+    if (!path) {
+        /* Not a directory */
+        ACR_SET_OS_ERROR(ACR_EFAULT);
+        return NULL;
+    }
+    if (!*path) {
+        /* Not a directory */
+        ACR_SET_OS_ERROR(ACR_ENOTDIR);
+        return NULL;
+    }
+    if (utf8_to_unicode_path(wpath, ACR_HBUFF_LEN - 3, path, ACR_HBUFF_LEN - 3))
+        return NULL;
+
+    if ((rc = GetFileAttributesW(wpath)) == INVALID_FILE_ATTRIBUTES)
+        return NULL;
+    if (!(rc & FILE_ATTRIBUTE_DIRECTORY)) {
+        /* Not a directory */
+        ACR_SET_OS_ERROR(ACR_ENOTDIR);
+        return NULL;
+    }
+    if (!(dir = malloc(sizeof(dir))))
+        return NULL;
+
+
+    rc = GetFullPathNameW(wpath, ACR_HBUFF_LEN - 3, dir->d_name, NULL);
+    if (rc == 0 || rc > ACR_HBUFF_LEN - 3) {
+        free(dir);
+        /* Invalid file name */
+        ACR_SET_OS_ERROR(ACR_EBADF);
+        return NULL;
+    }
+    len = wcslen(dir->d_name);
+    if (dir->d_name[len-1] != L'\\')
+        dir->d_name[len++]  = L'\\';
+    dir->d_name[len++] = L'*';
+    dir->d_name[len++] = 0;
+
+    dir->d_find = INVALID_HANDLE_VALUE;
+    dir->d_stat = 0;
+
+    return dir;
+}
+
+int closedir(DIR *dir)
+{
+    int rc = 0;
+    if (!dir) {
+        ACR_SET_OS_ERROR(ACR_EFAULT);
+        return -1;
+    }
+
+    if (dir->d_find != INVALID_HANDLE_VALUE) {
+        if (!FindClose(dir->d_find))
+            rc = GetLastError();
+    }
+    free(dir);
+    if (rc) {
+        SetLastError(rc);
+        return -1;
+    }
+    else
+        return 0;
+}
+
+void rewinddir(DIR *dir)
+{
+    if (!dir) {
+        ACR_SET_OS_ERROR(ACR_EFAULT);
+        return;
+    }
+
+    if (dir->d_find != INVALID_HANDLE_VALUE)
+        FindClose(dir->d_find);
+
+    dir->d_find = INVALID_HANDLE_VALUE;
+    dir->d_stat = 0;
+}
+
+off_t telldir(DIR *dir)
+{
+    if (!dir) {
+        ACR_SET_OS_ERROR(ACR_EFAULT);
+        return -1;
+    }
+
+    return dir->d_stat;
+}
+
+int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result)
+{
+    DWORD rc = 0;
+    WIN32_FIND_DATAW wfind;
+
+    if (!dir) {
+        return ACR_EFAULT;
+    }
+    if (dir->d_stat < 0) {
+        /* Already at the end
+         */
+        *result = NULL;
+        return 0;
+    }
+    else if (dir->d_stat == 0) {
+        /* Start the search
+         */
+        dir->d_find = FindFirstFileW(dir->d_name, &wfind);
+        if (dir->d_find == INVALID_HANDLE_VALUE) {
+            /* No files in the dir?
+             */
+            dir->d_stat = -1;
+        }
+        else
+            dir->d_stat =  1;
+    }
+    else {
+        /* Find the next entry
+         */
+        if (FindNextFileW(dir->d_find, &wfind)) {
+            /* Increment position counter
+             */
+            dir->d_stat++;
+        }
+        else {
+            rc = GetLastError();
+            if (rc == ERROR_NO_MORE_FILES)
+                rc = 0;
+            /* EOF or error
+             * Close the search handle
+             */
+            FindClose(dir->d_find);
+            dir->d_find = INVALID_HANDLE_VALUE;
+            dir->d_stat = -1;
+        }
+    }
+    if (dir->d_stat > 0) {
+        int mblen;
+        /* Fill in the dirent structure
+         */
+        mblen = WideCharToMultiByte(CP_UTF8, 0, wfind.cFileName, -1,
+                                    entry->d_name, 1023, NULL, 0);
+        if (!mblen)
+            return GetLastError();
+        entry->d_ino    = 0;
+        entry->d_type   = 0;
+        entry->d_off    = dir->d_stat;
+        entry->d_reclen = (unsigned short)(mblen - 1);
+        *result = entry;
+    }
+    else
+        *result = NULL;
+    return rc;
+}
+
+struct dirent *readdir(DIR *dir)
+{
+    int rc;
+    struct dirent *entry = NULL;
+
+    if (!dir) {
+        ACR_SET_OS_ERROR(ACR_EFAULT);
+        return NULL;
+    }
+
+    rc = readdir_r(dir, &dir->d_dir, &entry);
+    if (rc)
+        SetLastError(rc);
+
+    return entry;
+}
+
+void seekdir(DIR *dir, off_t pos)
+{
+    if (!dir) {
+        ACR_SET_OS_ERROR(ACR_EFAULT);
+        return;
+    }
+    if (pos < -1) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return;
+    }
+    else if (pos == -1) {
+        /* Seek past end */
+        if (dir->d_find != INVALID_HANDLE_VALUE)
+            FindClose(dir->d_find);
+
+        dir->d_find = INVALID_HANDLE_VALUE;
+        dir->d_stat = -1;
+    }
+    else {
+        rewinddir(dir);
+
+        while (dir->d_stat < pos) {
+            if (readdir(dir) == NULL)
+                break;
+        }
+    }
+
+}

Propchange: commons/sandbox/runtime/trunk/src/main/native/os/win32/dirent.c
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c?rev=802434&r1=802433&r2=802434&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c Sat Aug  8 18:48:04 2009
@@ -58,3 +58,94 @@
     return rname;
 }
 
+int utf8_to_unicode_path(wchar_t* retstr, size_t retlen,
+                         const char* srcstr, size_t unc)
+{
+    /* TODO: The computations could preconvert the string to determine
+     * the true size of the retstr, but that's a memory over speed
+     * tradeoff that isn't appropriate this early in development.
+     *
+     * Allocate the maximum string length based on leading 4
+     * characters of \\?\ (allowing nearly unlimited path lengths)
+     * plus the trailing null, then transform /'s into \\'s since
+     * the \\?\ form doesn't allow '/' path seperators.
+     *
+     * Note that the \\?\ form only works for local drive paths, and
+     * \\?\UNC\ is needed UNC paths.
+     */
+    size_t srcremains = strlen(srcstr) + 1;
+    wchar_t *t = retstr;
+
+    /* leave an extra space for double zero */
+    t[--retlen] = L'\0';
+    /* This is correct, we don't twist the filename if it is will
+     * definately be shorter than MAX_PATH.  It merits some
+     * performance testing to see if this has any effect, but there
+     * seem to be applications that get confused by the resulting
+     * Unicode \\?\ style file names, especially if they use argv[0]
+     * or call the Win32 API functions such as GetModuleName, etc.
+     * Not every application is prepared to handle such names.
+     *
+     * Note that a utf-8 name can never result in more wide chars
+     * than the original number of utf-8 narrow chars.
+     */
+    if (srcremains > unc) {
+        if (srcstr[1] == ':' && (srcstr[2] == '/' || srcstr[2] == '\\')) {
+            wcscpy (retstr, L"\\\\?\\");
+            retlen -= 4;
+            t += 4;
+        }
+        else if ((srcstr[0] == '/' || srcstr[0] == '\\')
+              && (srcstr[1] == '/' || srcstr[1] == '\\')
+              && (srcstr[2] != '?')) {
+            /* Skip the slashes */
+            srcstr += 2;
+            srcremains -= 2;
+            wcscpy (retstr, L"\\\\?\\UNC\\");
+            retlen -= 8;
+            t += 8;
+        }
+    }
+    if (!MultiByteToWideChar(CP_UTF8, 0, srcstr, -1, t, retlen))
+        return ACR_GET_OS_ERROR();
+    for (; *t; t++) {
+        if (*t == L'/')
+            *t = L'\\';
+    }
+    *t = L'\0';
+    return 0;
+}
+
+int unicode_to_utf8_path(char* retstr, size_t retlen,
+                         const wchar_t* srcstr)
+{
+    /* Skip the leading 4 characters if the path begins \\?\, or substitute
+     * // for the \\?\UNC\ path prefix, allocating the maximum string
+     * length based on the remaining string, plus the trailing null.
+     * then transform \\'s back into /'s since the \\?\ form never
+     * allows '/' path seperators, and APR always uses '/'s.
+     */
+    if (srcstr[0] == L'\\' && srcstr[1] == L'\\' &&
+        srcstr[2] == L'?'  && srcstr[3] == L'\\') {
+        if (srcstr[4] == L'U' && srcstr[5] == L'N' &&
+            srcstr[6] == L'C' && srcstr[7] == L'\\') {
+            srcstr += 8;
+            retstr[0] = '\\';
+            retstr[1] = '\\';
+            retlen -= 2;
+            retstr += 2;
+        }
+        else {
+            srcstr += 4;
+        }
+    }
+
+    if (!WideCharToMultiByte(CP_UTF8, 0, srcstr, -1,
+                             retstr, retlen, NULL, 0))
+        return ACR_GET_OS_ERROR();
+    for (; *retstr; retstr++) {
+        if (*retstr == '/')
+            *retstr = '\\';
+    }
+    return 0;
+}



Mime
View raw message