Author: mturk Date: Sat Oct 24 11:22:15 2009 New Revision: 829344 URL: http://svn.apache.org/viewvc?rev=829344&view=rev Log: Fix windows Path implementation
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr.h commons/sandbox/runtime/trunk/src/main/native/include/acr_port.h commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c commons/sandbox/runtime/trunk/src/main/native/os/win32/gui.c commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c commons/sandbox/runtime/trunk/src/main/native/port/basename.c commons/sandbox/runtime/trunk/src/main/native/port/dirname.c commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFileSys.java Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr.h?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/acr.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/acr.h Sat Oct 24 11:22:15 2009 @@ -253,7 +253,7 @@ typedef HANDLE acr_osd_t; #define ACR_INT64_C(val) (val##I64) #define ACR_UINT64_C(val) (val##UI64) -#define ACR_PPATH_MAX 1024 +#define ACR_PPATH_MAX 8192 #else /* !_MSC_VER */ typedef ssize_t acr_ssize_t; #ifdef _LP64 /* 64-bit Solaris */ @@ -283,7 +283,7 @@ #define ACR_INT64_C(val) (val##LL) #define ACR_UINT64_C(val) (val##ULL) #endif -#define ACR_PPATH_MAX PATH_MAX +#define ACR_PPATH_MAX (PATH_MAX * 2) #endif /* _MSC_VER */ #if CC_SIZEOF_VOIDP == 8 Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_port.h URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_port.h?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/include/acr_port.h (original) +++ commons/sandbox/runtime/trunk/src/main/native/include/acr_port.h Sat Oct 24 11:22:15 2009 @@ -47,12 +47,14 @@ * Reentrant version of dirname. * If buffer is NULL it uses static buffer. */ -char *dirname_r(const char *, char *, size_t); +char *dirname_r(const char *, char *, size_t); +wchar_t *dirname_w(const wchar_t *, wchar_t *, size_t); /** * Reentrant version of basename * If buffer is NULL it uses static buffer. */ -char *basename_r(const char *, char *, size_t); +char *basename_r(const char *, char *, size_t); +wchar_t *basename_w(const wchar_t *, wchar_t *, size_t); #if defined(ACR_WANT_STRSIGNAL) char *strsignal(int); 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=829344&r1=829343&r2=829344&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 Oct 24 11:22:15 2009 @@ -583,10 +583,12 @@ SYSDLL_SHELL32 = 6, /* shell32 From ShellAPI.h */ SYSDLL_ADVAPI32 = 7, /* advapi32 From WinBase.h */ SYSDLL_MSVCRT = 8, /* msvcrt */ - SYSDLL_JVM = 9, /* jvm From our own jvm.dll */ - SYSDLL_KTMW32 = 10, /* ktmw32 From Ktmw32.h */ + SYSDLL_RICHED32 = 9, /* riched32 */ + SYSDLL_MSHTML = 10, /* mshtml */ + SYSDLL_JVM = 11, /* jvm From our own jvm.dll */ + SYSDLL_KTMW32 = 12, /* ktmw32 From Ktmw32.h */ - SYSDLL_defined = 11 /* must define as last idx_ + 1 */ + SYSDLL_defined = 13 /* must define as last idx_ + 1 */ } acr_dlltoken_e; extern LPSYSTEM_INFO acr_osinf; Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c Sat Oct 24 11:22:15 2009 @@ -29,7 +29,6 @@ * Posix file path functions * */ -#define UCPATH_MAX (PATH_MAX * 2) #define IS_PATH_SEP(C) ((C) == '/' || (C) == '\0') static char *_rel_path(char *pcopy, size_t size, const char *path) @@ -155,10 +154,10 @@ */ char *acr_GetAbsolutePath(JNIEnv *_E, const char *path) { - char pcopy[UCPATH_MAX]; + char pcopy[ACR_PPATH_MAX]; char *cp; - cp = _abs_path(pcopy, UCPATH_MAX, path); + cp = _abs_path(pcopy, ACR_PPATH_MAX, path); if (!cp) { ACR_THROW_IO_ERRNO(); return NULL; @@ -229,9 +228,9 @@ UNREFERENCED_O; WITH_CSTR(path) { - char pcopy[UCPATH_MAX]; + char pcopy[ACR_PPATH_MAX]; char *abs; - if ((abs = _abs_path(pcopy, UCPATH_MAX, J2S(path)))) + if ((abs = _abs_path(pcopy, ACR_PPATH_MAX, J2S(path)))) rv = ACR_NewJavaStringA(_E, abs); else rc = ACR_GET_OS_ERROR(); @@ -251,14 +250,14 @@ UNREFERENCED_O; WITH_CSTR(root) { WITH_CSTR(path) { - char pcopy[UCPATH_MAX]; - char merge[UCPATH_MAX]; - char *abs; - strlcpy(merge, J2S(root), UCPATH_MAX); - strlcat(merge, "/", UCPATH_MAX); - strlcpy(merge, J2S(path), UCPATH_MAX); - if ((abs = _abs_path(pcopy, UCPATH_MAX, merge))) - rv = ACR_NewJavaStringA(_E, abs); + char pcopy[ACR_PPATH_MAX]; + char merge[ACR_PPATH_MAX]; + char *rel; + strlcpy(merge, J2S(root), ACR_PPATH_MAX); + strlcat(merge, "/", ACR_PPATH_MAX); + strlcpy(merge, J2S(path), ACR_PPATH_MAX); + if ((rel = _rel_path(pcopy, ACR_PPATH_MAX, merge))) + rv = ACR_NewJavaStringA(_E, rel); else rc = ACR_GET_OS_ERROR(); } END_WITH_CSTR(path); @@ -278,15 +277,15 @@ UNREFERENCED_O; WITH_CSTR(root) { WITH_CSTR(path) { - char pcopy[UCPATH_MAX]; - char merge[UCPATH_MAX]; - char *abs; + char pcopy[ACR_PPATH_MAX]; + char merge[ACR_PPATH_MAX]; + char *rel; /* Normalize path */ - if ((abs = _abs_path(pcopy, UCPATH_MAX, J2S(path)))) { + if ((rel = _rel_path(pcopy, ACR_PPATH_MAX, J2S(path)))) { /* Prepend root */ - strlcpy(merge, J2S(root), UCPATH_MAX); - strlcat(merge, "/", UCPATH_MAX); - strlcat(merge, abs, UCPATH_MAX); + strlcpy(merge, J2S(root), ACR_PPATH_MAX); + strlcat(merge, "/", ACR_PPATH_MAX); + strlcat(merge, rel, ACR_PPATH_MAX); rv = ACR_NewJavaStringA(_E, merge); } else @@ -305,9 +304,9 @@ UNREFERENCED_O; WITH_CSTR(path) { - char pcopy[UCPATH_MAX]; + char pcopy[ACR_PPATH_MAX]; char *rel; - if ((rel = _rel_path(pcopy, UCPATH_MAX, J2S(path)))) + if ((rel = _rel_path(pcopy, ACR_PPATH_MAX, J2S(path)))) rv = ACR_NewJavaStringA(_E, rel); else rc = ACR_GET_OS_ERROR(); Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/fsysio.c Sat Oct 24 11:22:15 2009 @@ -269,6 +269,9 @@ x_free(fp->name); x_free(fp); } + if (fo > 0) + acr_ioh_free(fo); + } return rc; @@ -378,6 +381,7 @@ if (!fdo) { rc = ACR_GET_OS_ERROR(); x_free(fp); + acr_ioh_free(fo); ACR_THROW_IO_IF_ERR(rc); return NULL; } Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/gui.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/gui.c?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/gui.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/gui.c Sat Oct 24 11:22:15 2009 @@ -44,11 +44,9 @@ HICON gui_h16Icon = NULL; HICON gui_h32Icon = NULL; HICON gui_h48Icon = NULL; -HMODULE gui_hMSHTML = NULL; HWND gui_DialogWnd = NULL; static HINSTANCE gui_hInstance = NULL; static HWND gui_hMainWnd = NULL; -static HMODULE gui_hRichedit = NULL; static UINT gui_ucNumLines = 3; static CHAR gui_szWndClass[MAX_PATH]; @@ -88,8 +86,6 @@ ICC_BAR_CLASSES; InitCommonControlsEx(&stCmn); - gui_hRichedit = LoadLibraryA("RICHED32.DLL"); - gui_hMSHTML = LoadLibraryA("MSHTML.DLL"); gui_h16Icon = LoadImage(gui_hInstance, MAKEINTRESOURCE(IDI_MAINICON), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); @@ -112,9 +108,6 @@ gui_Windows[i] = NULL; } } - FreeLibrary(gui_hRichedit); - FreeLibrary(gui_hMSHTML); - return TRUE; } Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/main.c Sat Oct 24 11:22:15 2009 @@ -183,13 +183,16 @@ "shell32.dll", "advapi32.dll", "msvcrt.dll", + "riched32.dll", + "mshtml.dll", "jvm.dll", "ktmw32.dll" }; static HMODULE late_dll_handles[SYSDLL_defined] = { NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, + NULL }; FARPROC acr_load_dll_func(acr_dlltoken_e fnLib, const char* fnName, int undec) Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c Sat Oct 24 11:22:15 2009 @@ -77,8 +77,10 @@ } } -#define UCPATH_MAX 8192 -#define IS_PATH_SEP(C) ((C) == L'/' || (C) == L'\0') +static int case_sensitive = 0; +#define IS_PATH_SEP(C) ((C) == L'/' || (C) == L'\0') +#define IS_DRIVE_CHAR(C) (((C) >= L'A' && (C) <= L'Z') || \ + ((C) >= L'a' && (C) <= L'z')) static wchar_t *_rel_path(wchar_t *pcopy, size_t size, const wchar_t *path) { @@ -88,7 +90,7 @@ size_t l; wcslcpy(pcopy, path, size); - /* Convert everything to back slashes + /* Convert everything to foward slashes */ BS2FS(pcopy); /* Remove \\?\ and replace \\?\UNC\ with \\ @@ -102,8 +104,7 @@ pcopy[l - 1] = L'\0'; rv = pcopy; - if (((pcopy[0] >= L'A' && pcopy[0] <= 'Z') || - (pcopy[0] >= L'a' && pcopy[0] <= 'z')) && pcopy[1] == L':') { + if (IS_DRIVE_CHAR(pcopy[0]) && pcopy[1] == L':') { /* Never go above C: */ pcopy += 2; } @@ -130,7 +131,7 @@ while (path[nd] == L'.') nd++; if (nd > 2) { - errno = ACR_EINVAL; + ACR_SET_OS_ERROR(ACR_EINVAL); return NULL; } if (IS_PATH_SEP(path[nd])) { @@ -186,7 +187,7 @@ else { rv = ACR_MALLOC(wchar_t, srclen + 9); if (!rv) { - /* Exception has already neen throw from ACR_Malloc + /* Exception has already been throw from ACR_Malloc */ return NULL; } @@ -199,52 +200,58 @@ } else { retstr = rv; - if (srclen > NON_UNC_PATH_LENGTH) { - if (srcstr[1] == L':' && (srcstr[2] == L'/' || srcstr[2] == L'\\')) { + if (IS_DRIVE_CHAR(srcstr[0]) && srcstr[1] == L':' && + (srcstr[2] == L'/' || srcstr[2] == L'\\')) { + if (srclen > NON_UNC_PATH_LENGTH) { wcscpy(retstr, L"\\\\?\\"); retstr += 4; retlen += 4; } - else if ((srcstr[0] == L'/' || srcstr[0] == L'\\') - && (srcstr[1] == L'/' || srcstr[1] == L'\\') - && (srcstr[2] != L'?')) { - if (srcstr[2] == L'.' && (srcstr[3] == L'/' || srcstr[3] == L'\\')) { - /* We have \\.\ sequence that can apear only - * if we have something like \\.\pipe\ - */ - wcscpy(retstr, L"\\\\.\\"); - retstr += 4; - srcstr += 4; - srclen -= 4; - } - else { - /* Skip the slashes and ? */ - srcstr += 2; - srclen -= 2; - wcscpy (retstr, L"\\\\?\\UNC\\"); - retlen += 8; - retstr += 8; - } - } - else if (srcstr[0] == '/' || srcstr[0] == '\\') { - int cd; - /* Addition to APR. Allow \FilePath - * and construct \\?\CurrenttDrive:\FilePath - * We use _getdrive CRT function + } + else if ((srcstr[0] == L'/' || srcstr[0] == L'\\') + && (srcstr[1] == L'/' || srcstr[1] == L'\\') + && (srcstr[2] != L'?')) { + if (srcstr[2] == L'.' && (srcstr[3] == L'/' || + srcstr[3] == L'\\')) { + /* We have \\.\ sequence that can apear only + * if we have something like \\.\pipe\ */ + wcscpy(retstr, L"\\\\.\\"); + retstr += 4; + srcstr += 4; + srclen -= 4; + } + else { + /* Skip the slashes and ? */ + srcstr += 2; + srclen -= 2; + wcscpy (retstr, L"\\\\?\\UNC\\"); + retlen += 6; + retstr += 8; + } + } + else if (srcstr[0] == '/' || srcstr[0] == '\\') { + int cd; + int ps = 0; + /* Addition to APR. Allow \FilePath + * and construct \\?\CurrenttDrive:\FilePath + * We use _getdrive CRT function + */ + if (srclen > NON_UNC_PATH_LENGTH) { wcscpy(retstr, L"\\\\?\\"); - if ((cd = _getdrive())) - retstr[4] = L'A' + cd - 1; - else { - /* C:\ should always be there - * If not later open will fail anyhow - */ - retstr[4] = L'C'; - } - retstr[5] = L':'; - retlen += 6; - retstr += 6; + ps = 4; + } + if ((cd = _getdrive())) + retstr[ps] = L'A' + cd - 1; + else { + /* C:\ should always be there + * If not later open will fail anyhow + */ + retstr[ps] = L'C'; } + retstr[ps + 1] = L':'; + retlen += (ps + 2); + retstr += (ps + 2); } memcpy(retstr, srcstr, srclen * sizeof(wchar_t)); @@ -261,10 +268,10 @@ if (s) { wchar_t *retstr; wchar_t *srcstr; - wchar_t buff[ACR_MBUFF_SIZ]; + wchar_t buff[ACR_PPATH_MAX]; size_t retlen = wcslen(s); - if (retlen > ACR_MBUFF_LEN) { + if (retlen >= ACR_PPATH_MAX) { srcstr = ACR_StrdupW(_E, THROW_FMARK, s); if (!srcstr) return NULL; @@ -298,11 +305,11 @@ * On Win32 for utf8 paths we always use the forwrd slashes. * They are converted to backward on translatio from utf8 */ - for (; *retstr; retstr++) { - if (*retstr == '\\') - *retstr = '/'; - } - r = (*_E)->NewString(_E, (const jchar *)s, (jsize)retlen); + BS2FS(retstr); + + r = (*_E)->NewString(_E, (const jchar *)retstr, (jsize)retlen); + if (srcstr != buff) + x_free(srcstr); } return r; } @@ -335,7 +342,8 @@ ACR_UnloadClass(_E, &_clazzn); } -ACR_DECLARE(jobject) ACR_NewPathObject(JNIEnv *_E, int type, const wchar_t *fpath) +ACR_DECLARE(jobject) ACR_NewPathObject(JNIEnv *_E, int type, + const wchar_t *fpath) { jstring path; if ((path = acr_NewJavaNativePathW(_E, fpath))) @@ -347,15 +355,29 @@ ACR_IO_EXPORT_DECLARE(void, Path, init0)(ACR_JNISTDARGS, jintArray p) { - jint ia[8]; - + jint ia[8]; + DWORD dw; UNREFERENCED_O; ia[0] = '\\'; ia[1] = ';'; - ia[2] = UCPATH_MAX; /* Use our path limit */ - ia[3] = NON_UNC_PATH_LENGTH; - ia[4] = 1; + ia[2] = ACR_PPATH_MAX - 1; /* Use our path limit */ + ia[3] = MAX_PATH - 2; + if (GetVolumeInformationW(L"C:\\", + NULL, + 0, + NULL, + NULL, + &dw, + NULL, + 0)) { + if ((dw & (FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES)) == + (FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES)) + case_sensitive = 1; + } + ia[4] = case_sensitive; + ia[5] = '%'; + ia[6] = '%'; (*_E)->SetIntArrayRegion(_E, p, 0, 8, &ia[0]); } @@ -366,9 +388,9 @@ UNREFERENCED_O; WITH_WSTR(path) { - wchar_t pcopy[UCPATH_MAX]; + wchar_t pcopy[ACR_PPATH_MAX]; wchar_t *rel; - if ((rel = _rel_path(pcopy, UCPATH_MAX, J2W(path)))) + if ((rel = _rel_path(pcopy, ACR_PPATH_MAX, J2W(path)))) rv = ACR_NewJavaStringW(_E, rel); else rc = ACR_GET_OS_ERROR(); @@ -392,16 +414,118 @@ jstring path, jstring other) { - int rc = 1; + int rc = 1; + int uc = case_sensitive; + DWORD dw; UNREFERENCED_O; WITH_WSTR(path) { WITH_WSTR(other) { - /* Presume case insensitive file system + /* XXX: We could catch instead doing volume check each time. */ - rc = _wcsicmp(J2W(path), J2W(other)); + if (GetVolumeInformationW(J2W(path), + NULL, + 0, + NULL, + NULL, + &dw, + NULL, + 0)) { + if ((dw & (FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES)) == + (FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES)) + uc = 1; + else + uc = 0; + } + if (uc) + rc = wcscmp(J2W(path), J2W(other)); + else + rc = _wcsicmp(J2W(path), J2W(other)); } END_WITH_WSTR(other); } END_WITH_WSTR(path); return rc; } + +ACR_IO_EXPORT_DECLARE(jstring, Path, merge0)(ACR_JNISTDARGS, + jstring root, + jstring path) +{ + int rc = 0; + jstring rv = NULL; + + UNREFERENCED_O; + WITH_WSTR(root) { + WITH_WSTR(path) { + wchar_t pcopy[ACR_PPATH_MAX]; + wchar_t merge[ACR_PPATH_MAX]; + wchar_t *rel; + wcslcpy(merge, J2W(root), ACR_PPATH_MAX); + wcslcat(merge, L"/", ACR_PPATH_MAX); + wcslcpy(merge, J2W(path), ACR_PPATH_MAX); + if ((rel = _rel_path(pcopy, ACR_PPATH_MAX, merge))) + rv = ACR_NewJavaStringW(_E, rel); + else + rc = ACR_GET_OS_ERROR(); + } END_WITH_WSTR(path); + } END_WITH_WSTR(root); + + ACR_THROW_IO_IF_ERR(rc); + return rv; +} + +ACR_IO_EXPORT_DECLARE(jstring, Path, merge1)(ACR_JNISTDARGS, + jstring root, + jstring path) +{ + int rc = 0; + jstring rv = NULL; + + UNREFERENCED_O; + WITH_WSTR(root) { + WITH_WSTR(path) { + wchar_t pcopy[ACR_PPATH_MAX]; + wchar_t merge[ACR_PPATH_MAX]; + wchar_t *rel; + /* Normalize path */ + if ((rel = _rel_path(pcopy, ACR_PPATH_MAX, J2W(path)))) { + /* Prepend root (should be already normalized) */ + wcslcpy(merge, J2W(root), ACR_PPATH_MAX); + wcslcat(merge, L"/", ACR_PPATH_MAX); + wcslcat(merge, rel, ACR_PPATH_MAX); + rv = ACR_NewJavaStringW(_E, merge); + } + else + rc = ACR_GET_OS_ERROR(); + } END_WITH_WSTR(path); + } END_WITH_WSTR(root); + + ACR_THROW_IO_IF_ERR(rc); + return rv; +} + +ACR_IO_EXPORT_DECLARE(jstring, Path, canon0)(ACR_JNISTDARGS, jstring path) +{ + int rc = 0; + jstring rv = NULL; + + UNREFERENCED_O; + WITH_WPATH(path) { + wchar_t pcopy[ACR_PPATH_MAX]; + DWORD len; + + len = GetFullPathNameW(J2W(path), + ACR_PPATH_MAX, + pcopy, + NULL); + if (len == 0) + rc = ACR_GET_OS_ERROR(); + else if (len >= ACR_PPATH_MAX) + rc = ACR_EOVERFLOW; + else + rv = acr_NewJavaNativePathW(_E, pcopy); + } END_WITH_WPATH(path); + + ACR_THROW_IO_IF_ERR(rc); + return rv; +} 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=829344&r1=829343&r2=829344&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 Oct 24 11:22:15 2009 @@ -109,11 +109,11 @@ * Note that the \\?\ form only works for local drive paths, and * \\?\UNC\ is needed UNC paths. */ - size_t srclen = strlen(srcstr) + 1; - wchar_t *t = retstr; + size_t srclen = strlen(srcstr) + 1; + wchar_t *retptr = retstr; /* leave an extra space for double zero */ - t[--retlen] = L'\0'; + --retlen; /* 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 @@ -125,61 +125,67 @@ * Note that a utf-8 name can never result in more wide chars * than the original number of utf-8 narrow chars. */ - if (srclen > NON_UNC_PATH_LENGTH) { - if (srcstr[1] == ':' && (srcstr[2] == '/' || srcstr[2] == '\\')) { - wcscpy (retstr, L"\\\\?\\"); + if (srcstr[1] == ':' && (srcstr[2] == '/' || srcstr[2] == '\\')) { + if (srclen > NON_UNC_PATH_LENGTH) { + wcscpy(retstr, L"\\\\?\\"); retlen -= 4; - t += 4; + retptr += 4; } - else if ((srcstr[0] == '/' || srcstr[0] == '\\') - && (srcstr[1] == '/' || srcstr[1] == '\\') - && (srcstr[2] != '?')) { - if (srcstr[2] == '.' && (srcstr[3] == '/' || srcstr[3] == '\\')) { - /* We have \\.\ sequence that can apear only - * if we have something like \\.\pipe\ - */ - wcscpy (retstr, L"\\\\.\\"); - srcstr += 4; - retlen -= 4; - t += 4; - } - else { - /* Skip the slashes and ? */ - srcstr += 2; - srclen -= 2; - wcscpy (retstr, L"\\\\?\\UNC\\"); - retlen -= 8; - t += 8; - } - } - else if (srcstr[0] == '/' || srcstr[0] == '\\') { - int cd; - /* Addition to APR. Allow \FilePath - * and construct \\?\CurrenttDrive:\FilePath - * We use _getdrive CRT function + } + else if ((srcstr[0] == '/' || srcstr[0] == '\\') + && (srcstr[1] == '/' || srcstr[1] == '\\') + && (srcstr[2] != '?')) { + if (srcstr[2] == '.' && (srcstr[3] == '/' || srcstr[3] == '\\')) { + /* We have \\.\ sequence that can apear only + * if we have something like \\.\pipe\ + */ + wcscpy(retstr, L"\\\\.\\"); + srcstr += 4; + retlen -= 4; + retptr += 4; + } + else { + /* Skip the slashes and ? */ + srcstr += 2; + srclen -= 2; + wcscpy(retstr, L"\\\\?\\UNC\\"); + retlen -= 8; + retptr += 8; + } + } + else if (srcstr[0] == '/' || srcstr[0] == '\\') { + int cd; + int ps = 0; + /* Addition to APR. Allow \FilePath + * and construct \\?\CurrenttDrive:\FilePath + * We use _getdrive CRT function + */ + if (srclen > NON_UNC_PATH_LENGTH) { + wcscpy(retstr, L"\\\\?\\"); + ps = 4; + } + if ((cd = _getdrive())) + retstr[ps] = L'A' + cd - 1; + else { + /* C:\ should always be there + * If not later open will fail anyhow */ - wcscpy (retstr, L"\\\\?\\"); - if ((cd = _getdrive())) - retstr[4] = L'A' + cd - 1; - else { - /* C:\ should always be there - * If not later open will fail anyhow - */ - retstr[4] = L'C'; - } - retstr[5] = L':'; - retlen -= 6; - t += 6; + retstr[ps] = L'C'; } + retstr[ps = 1] = L':'; + retlen -= (ps + 2); + retptr += (ps + 2); } if (!MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, - srcstr, (int)srclen, t, (int)retlen)) + srcstr, (int)srclen, retptr, (int)retlen)) { + *retstr = L'\0'; return ACR_GET_OS_ERROR(); - for (; *t; t++) { - if (*t == L'/') - *t = L'\\'; } - *t = L'\0'; + for (; *retptr; retptr++) { + if (*retptr == L'/') + *retptr = L'\\'; + } + *retptr = L'\0'; return 0; } @@ -207,8 +213,11 @@ } } - if (!WideCharToMultiByte(CP_UTF8, 0, srcstr, -1, retstr, (int)retlen, NULL, 0)) + if (!WideCharToMultiByte(CP_UTF8, 0, srcstr, -1, + retstr, (int)retlen, NULL, 0)) { + *retstr = '\0'; return ACR_GET_OS_ERROR(); + } /* Translate all back to forward slashes. * On Win32 for utf8 paths we always use the forwrd slashes. * They are converted to backward on translatio from utf8 @@ -244,10 +253,10 @@ srcstr += 4; } } - len = wcslen(srcstr); + len = wcslen(srcstr) + 1; if (len > retlen) return ACR_EOVERFLOW; - memcpy(retstr, srcstr, (len + 1) * sizeof(wchar_t)); + memcpy(retstr, srcstr, len * sizeof(wchar_t)); /* Translate all back to forward slashes. * On Win32 for utf8 paths we always use the forward slashes. * They are converted to backward on translation from acr. @@ -274,11 +283,11 @@ * Note that the \\?\ form only works for local drive paths, and * \\?\UNC\ is needed UNC paths. */ - size_t srclen = wcslen(srcstr) + 1; - wchar_t *t = retstr; + size_t srclen = wcslen(srcstr) + 1; + wchar_t *retptr = retstr; /* leave an extra space for double zero */ - t[--retlen] = L'\0'; + --retlen; /* 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 @@ -290,60 +299,67 @@ * Note that a utf-8 name can never result in more wide chars * than the original number of utf-8 narrow chars. */ - if (srclen > NON_UNC_PATH_LENGTH) { - if (srcstr[1] == L':' && (srcstr[2] == L'/' || srcstr[2] == L'\\')) { - wcscpy (retstr, L"\\\\?\\"); + if (srcstr[1] == L':' && (srcstr[2] == L'/' || srcstr[2] == L'\\')) { + if (srclen > NON_UNC_PATH_LENGTH) { + wcscpy(retstr, L"\\\\?\\"); retlen -= 4; - t += 4; + retptr += 4; } - else if ((srcstr[0] == L'/' || srcstr[0] == L'\\') - && (srcstr[1] == L'/' || srcstr[1] == L'\\') - && (srcstr[2] != L'?')) { - if (srcstr[2] == L'.' && (srcstr[3] == L'/' || srcstr[3] == L'\\')) { - /* We have \\.\ sequence that can apear only - * if we have something like \\.\pipe\ - */ - wcscpy (retstr, L"\\\\.\\"); - srcstr += 4; - retlen -= 4; - t += 4; - } - else { - /* Skip the slashes and ? */ - srcstr += 2; - srclen -= 2; - wcscpy (retstr, L"\\\\?\\UNC\\"); - retlen -= 8; - t += 8; - } - } - else if (srcstr[0] == L'/' || srcstr[0] == L'\\') { - int cd; - /* Addition to APR. Allow \FilePath - * and construct \\?\CurrenttDrive:\FilePath - * We use _getdrive CRT function + } + else if ((srcstr[0] == L'/' || srcstr[0] == L'\\') + && (srcstr[1] == L'/' || srcstr[1] == L'\\') + && (srcstr[2] != L'?')) { + if (srcstr[2] == L'.' && (srcstr[3] == L'/' || srcstr[3] == L'\\')) { + /* We have \\.\ sequence that can apear only + * if we have something like \\.\pipe\ */ - wcscpy (retstr, L"\\\\?\\"); - if ((cd = _getdrive())) - retstr[4] = L'A' + cd - 1; - else { - /* C:\ should always be there - * If not later open will fail anyhow - */ - retstr[4] = L'C'; - } - retstr[5] = L':'; - retlen -= 6; - t += 6; + wcscpy(retstr, L"\\\\.\\"); + srcstr += 4; + retlen -= 4; + retptr += 4; + } + else { + /* Skip the slashes and ? */ + srcstr += 2; + srclen -= 2; + wcscpy (retstr, L"\\\\?\\UNC\\"); + retlen -= 8; + retptr += 8; } } - if (srclen > retlen) + else if (srcstr[0] == L'/' || srcstr[0] == L'\\') { + int cd; + int ps = 0; + /* Addition to APR. Allow \FilePath + * and construct \\?\CurrenttDrive:\FilePath + * We use _getdrive CRT function + */ + if (srclen > NON_UNC_PATH_LENGTH) { + wcscpy(retstr, L"\\\\?\\"); + ps = 4; + } + if ((cd = _getdrive())) + retstr[ps] = L'A' + cd - 1; + else { + /* C:\ should always be there + * If not later open will fail anyhow + */ + retstr[ps] = L'C'; + } + retstr[ps + 1] = L':'; + retlen -= (ps + 2); + retptr += (ps + 2); + } + if (srclen > retlen) { + *retstr = L'\0'; return ACR_EOVERFLOW; - memcpy(t, srcstr, (srclen + 1) * sizeof(wchar_t)); - for (; *t; t++) { - if (*t == L'/') - *t = L'\\'; } + memcpy(retptr, srcstr, srclen * sizeof(wchar_t)); + for (; *retptr; retptr++) { + if (*retptr == L'/') + *retptr = L'\\'; + } + *retptr = L'\0'; return 0; } @@ -521,37 +537,35 @@ wchar_t *acr_GetAbsolutePath(JNIEnv *_E, HANDLE fh, const wchar_t *path) { - wchar_t buff[ACR_HBUFF_SIZ]; - wchar_t name[ACR_HBUFF_SIZ] = L""; + wchar_t buff[ACR_PPATH_MAX]; + wchar_t name[ACR_PPATH_MAX] = L""; DWORD nl; int rc = 0; if (ACR_HAVE_LATE_DLL_FUNC(GetFinalPathNameByHandleW)) { - nl = GetFinalPathNameByHandleW(fh, buff, ACR_HBUFF_LEN, FILE_NAME_NORMALIZED); + nl = GetFinalPathNameByHandleW(fh, buff, ACR_PPATH_MAX, + FILE_NAME_NORMALIZED); if (nl == 0) { rc = ACR_GET_OS_ERROR(); goto finally; } - if (nl >= ACR_HBUFF_SIZ) { + if (nl >= ACR_PPATH_MAX) { rc = ACR_EOVERFLOW; goto finally; } - if ((rc = unicode_to_acr_path(name, ACR_HBUFF_LEN, buff))) - goto finally; } else { - nl = GetFullPathNameW(path, ACR_HBUFF_LEN, buff, NULL); + nl = GetFullPathNameW(path, ACR_PPATH_MAX, buff, NULL); if (nl == 0) { rc = ACR_GET_OS_ERROR(); goto finally; } - if (nl >= ACR_HBUFF_SIZ) { + if (nl >= ACR_PPATH_MAX) { rc = ACR_EOVERFLOW; goto finally; } - if ((rc = unicode_to_acr_path(name, ACR_HBUFF_LEN, buff))) - goto finally; } + rc = unicode_to_acr_path(name, ACR_PPATH_MAX, buff); finally: if (rc) { Modified: commons/sandbox/runtime/trunk/src/main/native/port/basename.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/port/basename.c?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/port/basename.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/port/basename.c Sat Oct 24 11:22:15 2009 @@ -36,11 +36,15 @@ #include "acr_port.h" #if defined(WIN32) -#define IS_PS(c) ((c) == '/' || (c) == '\\') -#define NO_PS(c) ((c) != '/' && (c) != '\\') +#define IS_PSA(c) ((c) == '/' || (c) == '\\') +#define NO_PSA(c) ((c) != '/' && (c) != '\\') +#define IS_PSW(c) ((c) == L'/' || (c) == L'\\') +#define NO_PSW(c) ((c) != L'/' && (c) != L'\\') #else -#define IS_PS(c) ((c) == '/') -#define NO_PS(c) ((c) != '/') +#define IS_PSA(c) ((c) == '/') +#define NO_PSA(c) ((c) != '/') +#define IS_PSW(c) ((c) == L'/') +#define NO_PSW(c) ((c) != L'/') #endif char *basename_r(const char *path, char *bname, size_t blen) @@ -63,11 +67,11 @@ /* Strip any trailing slashes */ endp = path + strlen(path) - 1; - while (endp > path && IS_PS(*endp)) + while (endp > path && IS_PSA(*endp)) endp--; /* All slashes becomes "/" */ - if (endp == path && IS_PS(*endp)) { + if (endp == path && IS_PSA(*endp)) { bname[0] = '/'; bname[1] = '\0'; return bname; @@ -75,7 +79,7 @@ /* Find the start of the base */ startp = endp; - while (startp > path && NO_PS(*(startp - 1))) + while (startp > path && NO_PSA(*(startp - 1))) startp--; len = endp - startp + 1; @@ -85,5 +89,54 @@ } memcpy(bname, startp, len); bname[len] = '\0'; + + return bname; +} + +/* Unicode version of basename_r + */ +wchar_t *basename_w(const wchar_t *path, wchar_t *bname, size_t blen) +{ + size_t len; + const wchar_t *endp, *startp; + static wchar_t sbuf[ACR_PPATH_MAX]; + + if (!bname) { + bname = sbuf; + blen = sizeof(sbuf); + } + + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == L'\0') { + bname[0] = L'.'; + bname[1] = L'\0'; + return bname; + } + + /* Strip any trailing slashes */ + endp = path + wcslen(path) - 1; + while (endp > path && IS_PSW(*endp)) + endp--; + + /* All slashes becomes "/" */ + if (endp == path && IS_PSW(*endp)) { + bname[0] = L'/'; + bname[1] = L'\0'; + return bname; + } + + /* Find the start of the base */ + startp = endp; + while (startp > path && NO_PSW(*(startp - 1))) + startp--; + + len = endp - startp + 1; + if (len >= blen) { + errno = ENOMEM; + return NULL; + } + memcpy(bname, startp, len * sizeof(wchar_t)); + bname[len] = L'\0'; + return bname; } Modified: commons/sandbox/runtime/trunk/src/main/native/port/dirname.c URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/port/dirname.c?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/main/native/port/dirname.c (original) +++ commons/sandbox/runtime/trunk/src/main/native/port/dirname.c Sat Oct 24 11:22:15 2009 @@ -36,18 +36,22 @@ #include "acr_port.h" #if defined(WIN32) -#define IS_PS(c) ((c) == '/' || (c) == '\\') -#define NO_PS(c) ((c) != '/' && (c) != '\\') +#define IS_PSA(c) ((c) == '/' || (c) == '\\') +#define NO_PSA(c) ((c) != '/' && (c) != '\\') +#define IS_PSW(c) ((c) == L'/' || (c) == L'\\') +#define NO_PSW(c) ((c) != L'/' && (c) != L'\\') #else -#define IS_PS(c) ((c) == '/') -#define NO_PS(c) ((c) != '/') +#define IS_PSA(c) ((c) == '/') +#define NO_PSA(c) ((c) != '/') +#define IS_PSW(c) ((c) == L'/') +#define NO_PSW(c) ((c) != L'/') #endif char *dirname_r(const char *path, char *dname, size_t dlen) { size_t len; static char sbuf[ACR_PPATH_MAX]; - const char *endp; + const char *endp; if (!dname) { dname = sbuf; @@ -62,23 +66,23 @@ /* Strip any trailing slashes */ endp = path + strlen(path) - 1; - while (endp > path && IS_PS(*endp)) + while (endp > path && IS_PSA(*endp)) endp--; /* Find the start of the dir */ - while (endp > path && NO_PS(*endp)) + while (endp > path && NO_PSA(*endp)) endp--; /* Either the dir is "/" or there are no slashes */ if (endp == path) { - dname[0] = IS_PS(*endp) ? '/' : '.'; + dname[0] = IS_PSA(*endp) ? '/' : '.'; dname[1] = '\0'; return dname; } else { /* Move forward past the separating slashes */ do { endp--; - } while (endp > path && IS_PS(*endp)); + } while (endp > path && IS_PSA(*endp)); } len = endp - path + 1; @@ -88,5 +92,55 @@ } memcpy(dname, path, len); dname[len] = '\0'; + + return dname; +} + +wchar_t *dirname_w(const wchar_t *path, wchar_t *dname, size_t dlen) +{ + size_t len; + static wchar_t sbuf[ACR_PPATH_MAX]; + const wchar_t *endp; + + if (!dname) { + dname = sbuf; + dlen = sizeof(sbuf); + } + /* Empty or NULL string gets treated as "." */ + if (path == NULL || *path == L'\0') { + dname[0] = L'.'; + dname[1] = L'\0'; + return dname; + } + + /* Strip any trailing slashes */ + endp = path + wcslen(path) - 1; + while (endp > path && IS_PSW(*endp)) + endp--; + + /* Find the start of the dir */ + while (endp > path && NO_PSW(*endp)) + endp--; + + /* Either the dir is "/" or there are no slashes */ + if (endp == path) { + dname[0] = IS_PSW(*endp) ? L'/' : L'.'; + dname[1] = '\0'; + return dname; + } else { + /* Move forward past the separating slashes */ + do { + endp--; + } while (endp > path && IS_PSW(*endp)); + } + + len = endp - path + 1; + if (len >= dlen) { + errno = ENOMEM; + return NULL; + } + memcpy(dname, path, len * sizeof(wchar_t)); + dname[len] = L'\0'; + return dname; } Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java (original) +++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestAll.java Sat Oct 24 11:22:15 2009 @@ -42,7 +42,7 @@ suite.addTest(TestMemory.suite()); suite.addTest(TestNioByteBuffer.suite()); suite.addTest(TestPrivate.suite()); -// suite.addTest(TestFile.suite()); + suite.addTest(TestFile.suite()); suite.addTest(TestStrings.suite()); suite.addTest(TestSemaphore.suite()); suite.addTest(TestSharedMemory.suite()); @@ -61,7 +61,7 @@ // suite.addTest(TestSystem.suite()); // suite.addTest(TestSignal.suite()); -// suite.addTest(TestFileSys.suite()); + suite.addTest(TestFileSys.suite()); // Keep this as last test suite.addTest(TestCleanup.suite()); Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java (original) +++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java Sat Oct 24 11:22:15 2009 @@ -28,7 +28,7 @@ { private static native int ftest00(int d); - private static native File ftest01(String fname, int t); + private static native Path ftest01(String fname, int t); public static Test suite() { TestSuite suite = new TestSuite(TestFile.class); @@ -51,27 +51,27 @@ public void testFileType() throws Exception { - File f; + Path p; if (Os.TYPE.contains(OsType.UNIX)) - f = new File("/etc/hosts"); + p = new Path("/etc/hosts"); else - f = new File("C:/Windows/win.ini"); + p = new Path("C:/Windows/win.ini"); - FileType t = f.getFileType(); + FileType t = File.getFileType(p); if (Os.TYPE.contains(OsType.SOLARIS)) assertEquals("Type", FileType.LNK, t); else assertEquals("Type", FileType.REG, t); } - public void testFileTypeCreated() + public void testPathCreated() throws Exception { - File f = ftest01("foo", 4); - FileType t = f.getFileType(); - assertEquals("Type", FileType.BLK, t); + Path p = ftest01("foo", 0); + System.out.println("Path is " + p); } +/* public void testMakeSymlink() throws Exception { @@ -148,7 +148,6 @@ } } -/* public void testMakeHardlink() throws Exception { @@ -336,15 +335,17 @@ "foo/", "/foo/", "/foo/bar", - "c:/foo/../../bar", "foo/../bar", "foo/../../../bar", "/foo/../bar", - "/foo/../../../bar" + "/foo/../../../bar", + "c:/foo/../../../bar", + "//share/foo/../../../bar", + "//./pipe/foo/../../../bar", }; for (int i = 0; i < paths.length; i++) { Path p = new Path(paths[i]); - System.out.println("Path (" + paths[i] + ") is : " + p.getPath()); + System.out.println("Path (" + paths[i] + ") is : " + p.toString() + " -- " + p.toNativePath()); } } } Modified: commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFileSys.java URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFileSys.java?rev=829344&r1=829343&r2=829344&view=diff ============================================================================== --- commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFileSys.java (original) +++ commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFileSys.java Sat Oct 24 11:22:15 2009 @@ -43,6 +43,7 @@ Loader.load(); } +/* public void testFileSysOpenDef() throws Exception { @@ -119,18 +120,19 @@ System.out.println("Readed " + rd + " bytes from " + file.toString()); f.close(); } - + */ public void testFileStdout() throws Exception { byte [] buf = { (byte)'H', (byte)'i', (byte)'\n' }; assertEquals("FileType", FileType.PIPE, - FileInstance.STDOUT.getFileType()); - int wr = FileInstance.STDOUT.write(buf); + File.STDOUT.getFileType()); + int wr = File.STDOUT.write(buf); assertEquals("Written", 3, wr); } +/* public void testFileSysMktemp() throws Exception { @@ -154,7 +156,7 @@ System.out.println(" Inode : " + info.InodeId); f.close(); } - +*/ }