You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by wr...@apache.org on 2001/08/28 23:45:04 UTC
cvs commit: apr/include/arch/win32 fileio.h
wrowe 01/08/28 14:45:04
Modified: . apr.dsp libapr.dsp
file_io/win32 filepath.c
include/arch/win32 fileio.h
Added: file_io/win32 filesys.c
Log:
Split all win32 specific system calls from filepath.c into filesys.c
I don't care whether filepath.c remains in file_io/win32 or moves to
file_io/os2. This is now generic enough for both ports to build upon.
Revision Changes Path
1.81 +4 -0 apr/apr.dsp
Index: apr.dsp
===================================================================
RCS file: /home/cvs/apr/apr.dsp,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -r1.80 -r1.81
--- apr.dsp 2001/08/26 05:21:49 1.80
+++ apr.dsp 2001/08/28 21:45:04 1.81
@@ -117,6 +117,10 @@
# End Source File
# Begin Source File
+SOURCE=.\file_io\win32\filesys.c
+# End Source File
+# Begin Source File
+
SOURCE=.\file_io\win32\flock.c
# End Source File
# Begin Source File
1.43 +4 -0 apr/libapr.dsp
Index: libapr.dsp
===================================================================
RCS file: /home/cvs/apr/libapr.dsp,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -r1.42 -r1.43
--- libapr.dsp 2001/08/26 05:21:49 1.42
+++ libapr.dsp 2001/08/28 21:45:04 1.43
@@ -123,6 +123,10 @@
# End Source File
# Begin Source File
+SOURCE=.\file_io\win32\filesys.c
+# End Source File
+# Begin Source File
+
SOURCE=.\file_io\win32\flock.c
# End Source File
# Begin Source File
1.9 +20 -213 apr/file_io/win32/filepath.c
Index: filepath.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/filepath.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- filepath.c 2001/08/27 20:02:31 1.8
+++ filepath.c 2001/08/28 21:45:04 1.9
@@ -54,222 +54,17 @@
#include "apr.h"
#include "fileio.h"
-#include "apr_file_io.h"
#include "apr_strings.h"
-/* Win32 Exceptions:
- *
- * Note that trailing spaces and trailing periods are never recorded
- * in the file system, except by a very obscure bug where any file
- * that is created with a trailing space or period, followed by the
- * ':' stream designator on an NTFS volume can never be accessed again.
- * In other words, don't ever accept them when designating a stream!
- *
- * An interesting side effect is that two or three periods are both
- * treated as the parent directory, although the fourth and on are
- * not [strongly suggest all trailing periods are trimmed off, or
- * down to two if there are no other characters.]
- *
- * Leading spaces and periods are accepted, however.
- */
-static int is_fnchar(char ch)
-{
- /* No control code between 0 and 31 is allowed
- * The * ? < > codes all have wildcard effects
- * The " / \ : are exlusively separator tokens
- * The system doesn't accept | for any purpose.
- * Oddly, \x7f _is_ acceptable.
- */
- if (ch >= 0 && ch < 32)
- return 0;
-
- if (ch == '\"' || ch == '*' || ch == '/'
- || ch == ':' || ch == '<' || ch == '>'
- || ch == '?' || ch == '\\' || ch == '|')
- return 0;
-
- return 1;
-}
-
-
-static apr_status_t filepath_root_test(char *path,
- apr_pool_t *p)
-{
- apr_status_t rv;
-#if APR_HAS_UNICODE_FS
- apr_oslevel_e os_level;
- if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
- {
- apr_wchar_t wpath[APR_PATH_MAX];
- if (rv = utf8_to_unicode_path(wpath, sizeof(wpath)
- / sizeof(apr_wchar_t), path))
- return rv;
- rv = GetDriveTypeW(wpath);
- }
- else
-#endif
- rv = GetDriveType(path);
-
- if (rv == DRIVE_UNKNOWN || rv == DRIVE_NO_ROOT_DIR)
- return APR_EBADPATH;
- return APR_SUCCESS;
-}
-
-
-APR_DECLARE(apr_status_t) apr_filepath_get(char **rootpath,
- apr_pool_t *p)
-{
- char path[APR_PATH_MAX];
-#if APR_HAS_UNICODE_FS
- apr_oslevel_e os_level;
- if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
- {
- apr_wchar_t wpath[APR_PATH_MAX];
- apr_status_t rv;
- if (!GetCurrentDirectoryW(sizeof(wpath) / sizeof(apr_wchar_t), wpath))
- return apr_get_os_error();
- if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
- return rv;
- }
- else
-#endif
- {
- if (!GetCurrentDirectory(sizeof(path), path))
- return apr_get_os_error();
- }
- /* ###: We really should consider adding a flag to allow the user
- * to have the APR_FILEPATH_NATIVE result
- */
- for (*rootpath = path; **rootpath; ++*rootpath) {
- if (**rootpath == '\\')
- **rootpath = '/';
- }
- *rootpath = apr_pstrdup(p, path);
- return APR_SUCCESS;
-}
-
-
-static apr_status_t filepath_drive_get(char **rootpath,
- char drive,
- apr_pool_t *p)
-{
- char path[APR_PATH_MAX];
-#if APR_HAS_UNICODE_FS
- apr_oslevel_e os_level;
- if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
- {
- apr_wchar_t *ignored;
- apr_wchar_t wdrive[8];
- apr_wchar_t wpath[APR_PATH_MAX];
- apr_status_t rv;
- /* ???: This needs review, apparently "\\?\d:." returns "\\?\d:"
- * as if that is useful for anything.
- */
- wcscpy(wdrive, L"D:.");
- wdrive[0] = (apr_wchar_t)(unsigned char)drive;
- if (!GetFullPathNameW(wdrive, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
- return apr_get_os_error();
- if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
- return rv;
- }
- else
-#endif
- {
- char *ignored;
- char drivestr[4];
- drivestr[0] = drive;
- drivestr[1] = ':';
- drivestr[2] = '.';;
- drivestr[3] = '\0';
- if (!GetFullPathName(drivestr, sizeof(path), path, &ignored))
- return apr_get_os_error();
- }
- /* ###: We really should consider adding a flag to allow the user
- * to have the APR_FILEPATH_NATIVE result
- */
- for (*rootpath = path; **rootpath; ++*rootpath) {
- if (**rootpath == '\\')
- **rootpath = '/';
- }
- *rootpath = apr_pstrdup(p, path);
- return APR_SUCCESS;
-}
-
-
-static apr_status_t filepath_root_case(char **rootpath,
- char *root,
- apr_pool_t *p)
-{
-#if APR_HAS_UNICODE_FS
- apr_oslevel_e os_level;
- if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
- {
- apr_wchar_t *ignored;
- apr_wchar_t wpath[APR_PATH_MAX];
- apr_status_t rv;
- /* ???: This needs review, apparently "\\?\d:." returns "\\?\d:"
- * as if that is useful for anything.
- */
- {
- apr_wchar_t wroot[APR_PATH_MAX];
- if (rv = utf8_to_unicode_path(wroot, sizeof(wroot)
- / sizeof(apr_wchar_t), root))
- return rv;
- if (!GetFullPathNameW(wroot, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
- return apr_get_os_error();
- }
- {
- char path[APR_PATH_MAX];
- if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
- return rv;
- *rootpath = apr_pstrdup(p, path);
- }
- }
- else
-#endif
- {
- char path[APR_PATH_MAX];
- char *ignored;
- if (!GetFullPathName(root, sizeof(path), path, &ignored))
- return apr_get_os_error();
- *rootpath = apr_pstrdup(p, path);
- }
- return APR_SUCCESS;
-}
-
-
-APR_DECLARE(apr_status_t) apr_filepath_set(const char *rootpath,
- apr_pool_t *p)
-{
-#if APR_HAS_UNICODE_FS
- apr_oslevel_e os_level;
- if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
- {
- apr_wchar_t wpath[APR_PATH_MAX];
- apr_status_t rv;
- if (rv = utf8_to_unicode_path(wpath, sizeof(wpath)
- / sizeof(apr_wchar_t), rootpath))
- return rv;
- if (!SetCurrentDirectoryW(wpath))
- return apr_get_os_error();
- }
- else
-#endif
- {
- if (!SetCurrentDirectory(rootpath))
- return apr_get_os_error();
- }
- return APR_SUCCESS;
-}
-
-
-/* WinNT accepts several odd forms of a 'root' path. Under Unicode
+ /* WinNT accepts several odd forms of a 'root' path. Under Unicode
* calls (ApiFunctionW) the //?/C:/foo or //?/UNC/mach/share/foo forms
* are accepted. Ansi and Unicode functions both accept the //./C:/foo
* form under WinNT/2K. Since these forms are handled in the utf-8 to
* unicode translation phase, we don't want the user confused by them, so
* we will accept them but always return the canonical C:/ or //mach/share/
+ *
+ * OS2 appears immune from the nonsense :)
*/
APR_DECLARE(apr_status_t) apr_filepath_root(const char **rootpath,
@@ -284,10 +79,11 @@
if (testpath[0] == '/' || testpath[0] == '\\') {
if (testpath[1] == '/' || testpath[1] == '\\') {
- /* //server/share isn't the only // delimited syntax */
+
+#ifdef WIN32 /* //server/share isn't the only // delimited syntax */
if ((testpath[2] == '?' || testpath[2] == '.')
&& (testpath[3] == '/' || testpath[3] == '\\')) {
- if (is_fnchar(testpath[4]) && testpath[5] == ':')
+ if (IS_FNCHAR(testpath[4]) && testpath[5] == ':')
{
apr_status_t rv;
testpath += 4;
@@ -315,12 +111,13 @@
*/
return APR_EBADPATH;
}
+#endif /* WIN32 (non - //server/share syntax) */
/* Evaluate path of '//[machine/[share[/]]]' */
delim1 = testpath + 2;
do {
/* Protect against //X/ where X is illegal */
- if (*delim1 && !is_fnchar(*(delim1++)))
+ if (*delim1 && !IS_FNCHAR(*(delim1++)))
return APR_EBADPATH;
} while (*delim1 && *delim1 != '/' && *delim1 != '\\');
@@ -329,7 +126,7 @@
delim2 = delim1 + 1;
while (*delim2 && *delim2 != '/' && *delim2 != '\\') {
/* Protect against //machine/X/ where X is illegal */
- if (!is_fnchar(*(delim2++)))
+ if (!IS_FNCHAR(*(delim2++)))
return APR_EBADPATH;
}
@@ -418,7 +215,7 @@
}
/* Evaluate path of 'd:[/]' */
- if (is_fnchar(*testpath) && testpath[1] == ':')
+ if (IS_FNCHAR(*testpath) && testpath[1] == ':')
{
apr_status_t rv;
/* Validate that D:\ drive exists, test must be rooted
@@ -935,6 +732,14 @@
if ((rv = apr_stat(&finfo, path, APR_FINFO_TYPE | APR_FINFO_NAME, p))
== APR_SUCCESS) {
size_t namelen = strlen(finfo.name);
+
+#ifdef OS2 /* only has case folding, never aliases that change the length */
+
+ if (memcmp(finfo.name, path + keptlen, seglen) != 0) {
+ memcpy(path + keptlen, finfo.name, namelen);
+ }
+#else /* WIN32; here there be aliases that gire and gimble and change length */
+
if ((namelen != seglen) ||
(memcmp(finfo.name, path + keptlen, seglen) != 0))
{
@@ -961,6 +766,8 @@
seglen = namelen;
}
}
+#endif /* !OS2 (Whatever that alias was we're over it) */
+
/* That's it, the rest is path info.
* I don't know how we aught to handle this. Should
* we define a new error to indicate 'more info'?
1.1 apr/file_io/win32/filesys.c
Index: filesys.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include "apr.h"
#include "fileio.h"
#include "apr_strings.h"
/* Win32 Exceptions:
*
* Note that trailing spaces and trailing periods are never recorded
* in the file system, except by a very obscure bug where any file
* that is created with a trailing space or period, followed by the
* ':' stream designator on an NTFS volume can never be accessed again.
* In other words, don't ever accept them when designating a stream!
*
* An interesting side effect is that two or three periods are both
* treated as the parent directory, although the fourth and on are
* not [strongly suggest all trailing periods are trimmed off, or
* down to two if there are no other characters.]
*
* Leading spaces and periods are accepted, however.
* The * ? < > codes all have wildcard side effects
* The " / \ : are exclusively component separator tokens
* The system doesn't accept | for any (known) purpose
* Oddly, \x7f _is_ acceptable ;)
*/
const char c_is_fnchar[256] =
{/* Reject all ctrl codes... */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* " * / : < > ? */
1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,0,1,0,1,0,0,
/* \ */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,
/* : | */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,
/* High bit codes are accepted (subject to utf-8->Unicode xlation) */
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};
apr_status_t filepath_root_test(char *path, apr_pool_t *p)
{
apr_status_t rv;
#if APR_HAS_UNICODE_FS
apr_oslevel_e os_level;
if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
{
apr_wchar_t wpath[APR_PATH_MAX];
if (rv = utf8_to_unicode_path(wpath, sizeof(wpath)
/ sizeof(apr_wchar_t), path))
return rv;
rv = GetDriveTypeW(wpath);
}
else
#endif
rv = GetDriveType(path);
if (rv == DRIVE_UNKNOWN || rv == DRIVE_NO_ROOT_DIR)
return APR_EBADPATH;
return APR_SUCCESS;
}
apr_status_t filepath_drive_get(char **rootpath, char drive, apr_pool_t *p)
{
char path[APR_PATH_MAX];
#if APR_HAS_UNICODE_FS
apr_oslevel_e os_level;
if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
{
apr_wchar_t *ignored;
apr_wchar_t wdrive[8];
apr_wchar_t wpath[APR_PATH_MAX];
apr_status_t rv;
/* ???: This needs review, apparently "\\?\d:." returns "\\?\d:"
* as if that is useful for anything.
*/
wcscpy(wdrive, L"D:.");
wdrive[0] = (apr_wchar_t)(unsigned char)drive;
if (!GetFullPathNameW(wdrive, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
return apr_get_os_error();
if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
return rv;
}
else
#endif
{
char *ignored;
char drivestr[4];
drivestr[0] = drive;
drivestr[1] = ':';
drivestr[2] = '.';;
drivestr[3] = '\0';
if (!GetFullPathName(drivestr, sizeof(path), path, &ignored))
return apr_get_os_error();
}
/* ###: We really should consider adding a flag to allow the user
* to have the APR_FILEPATH_NATIVE result
*/
for (*rootpath = path; **rootpath; ++*rootpath) {
if (**rootpath == '\\')
**rootpath = '/';
}
*rootpath = apr_pstrdup(p, path);
return APR_SUCCESS;
}
apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p)
{
#if APR_HAS_UNICODE_FS
apr_oslevel_e os_level;
if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
{
apr_wchar_t *ignored;
apr_wchar_t wpath[APR_PATH_MAX];
apr_status_t rv;
/* ???: This needs review, apparently "\\?\d:." returns "\\?\d:"
* as if that is useful for anything.
*/
{
apr_wchar_t wroot[APR_PATH_MAX];
if (rv = utf8_to_unicode_path(wroot, sizeof(wroot)
/ sizeof(apr_wchar_t), root))
return rv;
if (!GetFullPathNameW(wroot, sizeof(wpath) / sizeof(apr_wchar_t), wpath, &ignored))
return apr_get_os_error();
}
{
char path[APR_PATH_MAX];
if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
return rv;
*rootpath = apr_pstrdup(p, path);
}
}
else
#endif
{
char path[APR_PATH_MAX];
char *ignored;
if (!GetFullPathName(root, sizeof(path), path, &ignored))
return apr_get_os_error();
*rootpath = apr_pstrdup(p, path);
}
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_filepath_get(char **rootpath,
apr_pool_t *p)
{
char path[APR_PATH_MAX];
#if APR_HAS_UNICODE_FS
apr_oslevel_e os_level;
if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
{
apr_wchar_t wpath[APR_PATH_MAX];
apr_status_t rv;
if (!GetCurrentDirectoryW(sizeof(wpath) / sizeof(apr_wchar_t), wpath))
return apr_get_os_error();
if ((rv = unicode_to_utf8_path(path, sizeof(path), wpath)))
return rv;
}
else
#endif
{
if (!GetCurrentDirectory(sizeof(path), path))
return apr_get_os_error();
}
/* ###: We really should consider adding a flag to allow the user
* to have the APR_FILEPATH_NATIVE result
*/
for (*rootpath = path; **rootpath; ++*rootpath) {
if (**rootpath == '\\')
**rootpath = '/';
}
*rootpath = apr_pstrdup(p, path);
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_filepath_set(const char *rootpath,
apr_pool_t *p)
{
#if APR_HAS_UNICODE_FS
apr_oslevel_e os_level;
if (!apr_get_oslevel(p, &os_level) && os_level >= APR_WIN_NT)
{
apr_wchar_t wpath[APR_PATH_MAX];
apr_status_t rv;
if (rv = utf8_to_unicode_path(wpath, sizeof(wpath)
/ sizeof(apr_wchar_t), rootpath))
return rv;
if (!SetCurrentDirectoryW(wpath))
return apr_get_os_error();
}
else
#endif
{
if (!SetCurrentDirectory(rootpath))
return apr_get_os_error();
}
return APR_SUCCESS;
}
1.55 +32 -0 apr/include/arch/win32/fileio.h
Index: fileio.h
===================================================================
RCS file: /home/cvs/apr/include/arch/win32/fileio.h,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- fileio.h 2001/06/27 19:40:53 1.54
+++ fileio.h 2001/08/28 21:45:04 1.55
@@ -212,6 +212,38 @@
};
};
+/* There are many goofy characters we can't accept. Here's the list.
+ */
+extern const char c_is_fnchar[256];
+
+#define IS_FNCHAR(c) c_is_fnchar[(unsigned char)c]
+
+
+/* If the user passes APR_FILEPATH_TRUENAME to either
+ * apr_filepath_root or apr_filepath_merge, this fn determines
+ * that the root really exists. It's expensive, wouldn't want
+ * to do this too frequenly.
+ */
+apr_status_t filepath_root_test(char *path, apr_pool_t *p);
+
+
+/* The apr_filepath_merge wants to canonicalize the cwd to the
+ * addpath if the user passes NULL as the old root path (this
+ * isn't true of an empty string "", which won't be concatinated.
+ *
+ * But we need to figure out what the cwd of a given volume is,
+ * when the user passes D:foo. This fn will determine D:'s cwd.
+ */
+apr_status_t filepath_drive_get(char **rootpath, char drive, apr_pool_t *p);
+
+
+/* If the user passes d: vs. D: (or //mach/share vs. //MACH/SHARE),
+ * we need to fold the case to canonical form. This function is
+ * supposed to do so.
+ */
+apr_status_t filepath_root_case(char **rootpath, char *root, apr_pool_t *p);
+
+
apr_status_t file_cleanup(void *);
/**