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 2009/10/21 15:05:02 UTC
svn commit: r828002 - in /commons/sandbox/runtime/trunk/src:
main/java/org/apache/commons/runtime/io/ main/native/ main/native/include/
main/native/os/unix/ main/native/os/win32/ test/org/apache/commons/runtime/
Author: mturk
Date: Wed Oct 21 13:05:01 2009
New Revision: 828002
URL: http://svn.apache.org/viewvc?rev=828002&view=rev
Log:
Add Path class support and our path format (same as for APR)
Added:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java (with props)
commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c (with props)
commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c (with props)
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Directory.java
commons/sandbox/runtime/trunk/src/main/native/Makefile.in
commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h
commons/sandbox/runtime/trunk/src/main/native/os/unix/dir.c
commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c
commons/sandbox/runtime/trunk/src/test/org/apache/commons/runtime/TestFile.java
Modified: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Directory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Directory.java?rev=828002&r1=828001&r2=828002&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Directory.java (original)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Directory.java Wed Oct 21 13:05:01 2009
@@ -58,10 +58,10 @@
/**
* Open a {@code Directory} for reading.
*/
- public Directory(File path)
+ public Directory(Path path)
throws FileNotFoundException, IOException, SecurityException
{
- this.path = path.getPath();
+ this.path = path.toString();
dd = open0(this.path);
}
@@ -115,12 +115,12 @@
private static native int mkdir0(String path, int perms);
private static native int mkdir1(String path, int perms);
- public static boolean create(File path, EnumSet<FileProtection> prot)
+ public static boolean create(Path path, EnumSet<FileProtection> prot)
throws FileNotFoundException, IOException, SecurityException
{
int rc;
- rc = mkdir0(path.getPath(), FileProtection.bitmapOf(prot));
+ rc = mkdir0(path.toString(), FileProtection.bitmapOf(prot));
if (rc == 0)
return true;
if (Status.STATUS_IS_EEXIST(rc))
@@ -138,13 +138,13 @@
throw new IOException(Status.describe(rc));
}
- public static boolean createRecursive(File path,
+ public static boolean createRecursive(Path path,
EnumSet<FileProtection> prot)
throws IOException, SecurityException
{
int rc;
- rc = mkdir1(path.getPath(), FileProtection.bitmapOf(prot));
+ rc = mkdir1(path.toString(), FileProtection.bitmapOf(prot));
if (rc == 0)
return true;
if (Status.STATUS_IS_EEXIST(rc))
@@ -173,10 +173,10 @@
* @throws SecurityException if Write access to the directory specified
* by {@code path} is denied.
*/
- public static File createTemp(File path, String prefix)
+ public static File createTemp(Path path, String prefix)
throws IOException, SecurityException
{
- String tmp = tmpdir0(path.getPath(), prefix);
+ String tmp = tmpdir0(path.toString(), prefix);
return new File(tmp, FileType.DIR);
}
@@ -198,7 +198,7 @@
return new File(tmp, FileType.DIR);
}
- private static File tmpDir;
+ private static Path tmpDir;
private static native String tmpdir1(String paths);
/**
* Get system temporary directory path.
@@ -210,16 +210,42 @@
* @throws SecurityException if Write access to directories listed inside
* {@code searchPath} is denied.
*/
- public synchronized static File getTemp(String searchPath)
+ public synchronized static Path getTempPath(String searchPath)
throws SecurityException
{
String dir = tmpdir1(searchPath);
if (dir == null)
throw new SecurityException();
- tmpDir = new File(dir, FileType.DIR);
+ tmpDir = new Path(dir);
return tmpDir;
}
+ public static native String cur0()
+ throws IOException;
+ public static Path getCurrentPath()
+ throws IOException
+ {
+ return new Path(cur0());
+ }
+
+ public static native int cwd0(String path)
+ throws IOException;
+ public static void setCurrentPath(Path path)
+ throws IOException
+ {
+ int rc = cwd0(path.toString());
+ if (rc != 0) {
+ throw new IOException(Status.describe(rc));
+ }
+ }
+ public static void setCurrentPath(String path)
+ throws IOException
+ {
+ int rc = cwd0(path);
+ if (rc != 0) {
+ throw new IOException(Status.describe(rc));
+ }
+ }
}
Added: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java?rev=828002&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java (added)
+++ commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java Wed Oct 21 13:05:01 2009
@@ -0,0 +1,259 @@
+/* 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.
+ */
+
+package org.apache.commons.runtime.io;
+
+import java.io.IOException;
+import java.net.URI;
+import org.apache.commons.runtime.Os;
+import org.apache.commons.runtime.OsType;
+import org.apache.commons.runtime.util.StringManager;
+
+/**
+ * An abstract representation of file and directory pathnames. The path
+ * is not required to exit.
+ * <p>
+ * All paths are in posix form with (@code /} character as path separator.
+ * </p>
+ * <p>
+ * Windows accepts several odd forms of a {@code 'root'} path.
+ * Under Unicode calls {@code (ApiFunctionW)} the {@code //?/C:/foo} or
+ * {@code //?/UNC/mach/share/foo} forms are accepted.
+ * Ansi and Unicode functions both accept the {@code //./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
+ * {@code C:/} or {@code //mach/share/}. One distinction for path is
+ * NT pipe naming that starts with {@code //./pipe/}.
+ * </p>
+ */
+public final class Path implements Comparable<Path>
+{
+
+ /**
+ * Native {@code Path} separator character.
+ */
+ public static final char SEPARATOR;
+ /**
+ * Native {@code Path} components separator character.
+ */
+ public static final char DELIMITER;
+ /**
+ * Maximum length of {@code Path} supported by platform.
+ */
+ public static final int MAX;
+ /**
+ * {@code true} if file system is case sensitive.
+ */
+ public static final boolean CASE_SENSITIVE;
+
+ private static native void init0(int [] p);
+ static {
+ int [] ia = new int[4];
+ init0(ia);
+ SEPARATOR = (char)ia[0];
+ DELIMITER = (char)ia[1];
+ MAX = ia[2];
+ CASE_SENSITIVE = ia[3] == 1;
+ }
+
+ private static native String normal0(String path)
+ throws IOException;
+ /**
+ * Remove all embedded {@code .} and {@code ..}
+ * characters from the {@code path}.
+ */
+ private static String normal(final String path)
+ throws IllegalArgumentException
+ {
+ try {
+ return normal0(path);
+ } catch (IOException ex) {
+ throw new IllegalArgumentException(ex.getMessage());
+ }
+ }
+ private static native String merge0(String root, String path)
+ throws IOException;
+ private static native String merge1(String root, String path)
+ throws IOException;
+ /**
+ * Merge two paths.
+ */
+ private static String merge(final String root, final String path,
+ boolean allowAboveRoot)
+ throws IllegalArgumentException
+ {
+ try {
+ if (allowAboveRoot)
+ return merge0(root, path);
+ else
+ return merge1(root, path);
+ } catch (IOException ex) {
+ throw new IllegalArgumentException(ex.getMessage());
+ }
+ }
+
+ /**
+ * Normalized Path
+ */
+ private String path;
+
+ private Path()
+ throws NullPointerException, IOException
+ {
+ }
+ /**
+ * Creates a new {@code Path} instance from a {@code parent} pathname
+ * string and a {@code child} pathname string.
+ * <p>
+ * If {@code parent} is {@code null} then the new {@code Path} instance
+ * is created as if by invoking the single-argument {@code Path}
+ * constructor on the given {@code child} pathname string.
+ * </p>
+ * <p>
+ * Otherwise the {@code parent} pathname string is taken to denote a
+ * directory, and the {@code child} pathname string is taken to denote
+ * either a directory or a file. If the {@code child} pathname string is
+ * absolute then it is converted into a relative pathname in a
+ * system-dependent way. If {@code parent} is the empty string then the
+ * new {@code Path} instance is created by converting child into an
+ * abstract pathname and resolving the result against a system-dependent
+ * default directory. Otherwise each pathname string is converted into an
+ * abstract pathname and the child abstract pathname is resolved
+ * against the parent.
+ *
+ * @param parent The parent pathname string.
+ * @param child The child pathname string.
+ * @throws NullPointerException If the {@code child} is {@code null}.
+ */
+ public Path(String parent, String child)
+ throws NullPointerException, IllegalArgumentException
+ {
+ if (parent == null || child == null)
+ throw new NullPointerException();
+ path = merge(parent, child, true);
+ }
+
+ /**
+ * Creates a new {@code Path} instance from a {@code parent} abstract
+ * pathname and a {@code child} pathname string.
+ * <p>
+ * If {@code parent} is {@code null} then the new {@code Path} instance is
+ * created as if by invoking the single-argument {@code Path} constructor
+ * on the given {@code child} pathname string.
+ * </p>
+ * <p>
+ * Otherwise the {@code parent} abstract pathname is taken to denote a
+ * directory, and the {@code child} pathname string is taken to denote
+ * either a directory or a file. If the {@code child} pathname string is
+ * absolute then it is converted into a relative pathname in a
+ * system-dependent way. If {@code parent} is the empty abstract pathname
+ * then the new {@code Path} instance is created by converting {@code child}
+ * into an abstract pathname and resolving the result against a
+ * system-dependent default directory. Otherwise each pathname string
+ * is converted into an abstract pathname and the child abstract pathname
+ * is resolved against the parent.
+ *
+ * @param parent The parent abstract pathname.
+ * @param child The child pathname string.
+ * @throws NullPointerException If the {@code child} is {@code null}.
+ */
+ public Path(Path parent, String child)
+ throws NullPointerException, IllegalArgumentException
+ {
+ if (parent == null || child == null)
+ throw new NullPointerException();
+ path = merge(parent.path, child, false);
+ }
+
+ /**
+ * Create new {@code Path} instance by converting the given pathname
+ * into an abstract pathname. If the given string is the empty path,
+ * then the result is empty pathname.
+ *
+ * @param pathname A pathname string.
+ * @throws NullPointerException If the {@code path} is {@code null}.
+ * @throws IllegalArgumentException If the {@code path} is invalid.
+ */
+ public Path(String path)
+ throws NullPointerException, IllegalArgumentException
+
+ {
+ if (path == null)
+ throw new NullPointerException();
+ this.path = normal(path);
+ }
+
+ public static native int compare0(String path, String other);
+ public int compareTo(Path other)
+ {
+ if (other == null)
+ return 1;
+ else
+ return compare0(path, other.path);
+ }
+
+ public static native String native0(String path)
+ throws Exception;
+ /**
+ * Get this abstract pathname platform native string.
+ * <p>
+ * Returned pathname is platform dependant.
+ * </p>
+ */
+ public String getPath()
+ {
+ try {
+ return native0(path);
+ } catch (Exception ex) {
+ return path;
+ }
+ }
+
+ /**
+ * Get this abstract pathname string.
+ * <p>
+ * Returned pathname is always in normalized form with all embedded
+ * backpaths removed and resolved.
+ * </p>
+ */
+ @Override
+ public String toString()
+ {
+ return path;
+ }
+
+ private static native String canon0(String path)
+ throws Exception;
+ /**
+ * Returns canonical pathname of this abstract pathname.
+ * <p>
+ * </p>
+ *
+ * @return The canonical pathname string denoting the same file or
+ * directory as this abstract pathname.
+ */
+ public static String getCanonical(String path)
+ throws IOException
+ {
+ try {
+ return canon0(path);
+ } catch (Exception ex) {
+ throw new IOException(ex.getMessage());
+ }
+ }
+
+}
Propchange: commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Path.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.in
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.in?rev=828002&r1=828001&r2=828002&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.in Wed Oct 21 13:05:01 2009
@@ -131,6 +131,7 @@
$(SRCDIR)/os/unix/memalign.$(OBJ) \
$(SRCDIR)/os/unix/mmap.$(OBJ) \
$(SRCDIR)/os/unix/mutex.$(OBJ) \
+ $(SRCDIR)/os/unix/path.$(OBJ) \
$(SRCDIR)/os/unix/pipe.$(OBJ) \
$(SRCDIR)/os/unix/proc.$(OBJ) \
$(SRCDIR)/os/unix/secmem.$(OBJ) \
@@ -169,6 +170,7 @@
$(SRCDIR)/os/unix/memalign.$(OBJ) \
$(SRCDIR)/os/unix/mmap.$(OBJ) \
$(SRCDIR)/os/unix/mutex.$(OBJ) \
+ $(SRCDIR)/os/unix/path.$(OBJ) \
$(SRCDIR)/os/unix/pipe.$(OBJ) \
$(SRCDIR)/os/unix/proc.$(OBJ) \
$(SRCDIR)/os/unix/secmem.$(OBJ) \
@@ -203,6 +205,7 @@
$(SRCDIR)/os/unix/user.$(OBJ) \
$(SRCDIR)/os/unix/memalign.$(OBJ) \
$(SRCDIR)/os/unix/mmap.$(OBJ) \
+ $(SRCDIR)/os/unix/path.$(OBJ) \
$(SRCDIR)/os/unix/pipe.$(OBJ) \
$(SRCDIR)/os/unix/proc.$(OBJ) \
$(SRCDIR)/os/unix/secmem.$(OBJ) \
@@ -240,6 +243,7 @@
$(SRCDIR)/os/unix/memalign.$(OBJ) \
$(SRCDIR)/os/unix/mmap.$(OBJ) \
$(SRCDIR)/os/unix/mutex.$(OBJ) \
+ $(SRCDIR)/os/unix/path.$(OBJ) \
$(SRCDIR)/os/unix/pipe.$(OBJ) \
$(SRCDIR)/os/unix/proc.$(OBJ) \
$(SRCDIR)/os/unix/secmem.$(OBJ) \
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=828002&r1=828001&r2=828002&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Wed Oct 21 13:05:01 2009
@@ -127,6 +127,7 @@
$(SRCDIR)/os/win32/module.$(OBJ) \
$(SRCDIR)/os/win32/mutex.$(OBJ) \
$(SRCDIR)/os/win32/ntpipe.$(OBJ) \
+ $(SRCDIR)/os/win32/path.$(OBJ) \
$(SRCDIR)/os/win32/pipe.$(OBJ) \
$(SRCDIR)/os/win32/posix.$(OBJ) \
$(SRCDIR)/os/win32/registry.$(OBJ) \
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h?rev=828002&r1=828001&r2=828002&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h (original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr_private.h Wed Oct 21 13:05:01 2009
@@ -118,6 +118,18 @@
(*_E)->ReleaseByteArrayElements(_E, V, (jbyte *)_c##V, JNI_ABORT); \
} } else ACR_ThrowException(_E, THROW_FMARK, ACR_EX_ENULL, 0)
+#define WITH_WPATH(V) \
+ if ((V)) { \
+ wchar_t _b##V[ACR_MBUFF_SIZ]; \
+ wchar_t *_w##V = ACR_GetJavaNativePathW(_E, (V), _b##V); \
+ if (!_w##V) goto _cw##V;
+
+#define WITH_ZWPATH(V) \
+ if (_E) { \
+ wchar_t _b##V[ACR_MBUFF_SIZ]; \
+ wchar_t *_w##V = ACR_GetJavaNativePathW(_E, (V), _b##V); \
+ if (!_w##V && (V)) goto _cw##V;
+
#define WITH_WSTR(V) \
if ((V)) { \
wchar_t _b##V[ACR_MBUFF_SIZ]; \
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/dir.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/dir.c?rev=828002&r1=828001&r2=828002&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/dir.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/dir.c Wed Oct 21 13:05:01 2009
@@ -277,3 +277,33 @@
else
return NULL;
}
+
+ACR_IO_EXPORT_DECLARE(jstring, Directory, getcwd0)(ACR_JNISTDARGS)
+{
+ size_t l;
+ char path[PATH_MAX];
+
+ UNREFERENCED_O;
+ if (!getcwd(path, sizeof(path))) {
+ ACR_THROW_IO_ERRNO();
+ }
+ l = strlen(path);
+ if (l > 1 && path[l - 1] == '/')
+ path[l - 1] = '\0';
+ return ACR_NewJavaStringA(_E, path);
+}
+
+ACR_IO_EXPORT_DECLARE(jint, Directory, chdir0)(ACR_JNISTDARGS, jstring path)
+{
+ int rv = ACR_EINVAL;
+
+ UNREFERENCED_O;
+ WITH_ZCSTR(path) {
+ if (chdir(J2S(path)))
+ rv = ACR_GET_OS_ERROR();
+ else
+ rv = 0;
+ } END_WITH_CSTR(path);
+
+ return rv;
+}
Added: 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=828002&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c Wed Oct 21 13:05:01 2009
@@ -0,0 +1,302 @@
+/* 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.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+#include "acr_port.h"
+#include "acr_error.h"
+#include "acr_string.h"
+#include "acr_descriptor.h"
+#include "acr_file.h"
+#include "acr_port.h"
+
+/**
+ * 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)
+{
+ char *cp;
+ int ch = '/';
+ size_t l;
+
+ strlcpy(pcopy, path, size);
+ l = strlen(pcopy);
+ if (l > 1 && pcopy[l - 1] == '/')
+ pcopy[l - 1] = '\0';
+
+ path = cp = pcopy;
+ while (*path) {
+ if (IS_PATH_SEP(ch) && *path == '.') {
+ size_t nd = 0;
+ while (path[nd] == '.')
+ nd++;
+ if (nd > 2) {
+ errno = ACR_EINVAL;
+ return NULL;
+ }
+ if (IS_PATH_SEP(path[nd])) {
+ path += nd;
+ if (*path)
+ path++;
+ while (nd > 1) {
+ if (cp > pcopy + 1) {
+ cp--;
+ while (cp > pcopy) {
+ if (IS_PATH_SEP(*(cp - 1)))
+ break;
+ cp--;
+ }
+ }
+ else
+ break;
+ nd--;
+ }
+ }
+ else
+ ch = *cp++ = *path++;
+ }
+ else
+ ch = *cp++ = *path++;
+ }
+ *cp = '\0';
+ /* Duplicate the final path
+ */
+ return pcopy;
+
+}
+
+static char *_abs_path(char *pcopy, size_t size, const char *path)
+{
+
+ char *cp;
+ int ch = '/';
+ size_t l;
+ if (*path == '/' && !strstr(path, "./")) {
+ /* Already an absolute path
+ */
+ strlcpy(pcopy, path, size);
+ return pcopy;
+ }
+ if (!IS_PATH_SEP(*path)) {
+ if (!getcwd(pcopy, PATH_MAX)) {
+ return NULL;
+ }
+ strlcat(pcopy, "/", size);
+ strlcat(pcopy, path, size);
+ }
+ else
+ strlcpy(pcopy, path, size);
+ l = strlen(pcopy);
+ if (l > 1 && pcopy[l - 1] == '/')
+ pcopy[l - 1] = '\0';
+
+ path = cp = pcopy;
+ while (*path) {
+ if (IS_PATH_SEP(ch) && *path == '.') {
+ size_t nd = 0;
+ while (path[nd] == '.')
+ nd++;
+ if (nd > 2) {
+ errno = ACR_EINVAL;
+ return NULL;
+ }
+ if (IS_PATH_SEP(path[nd])) {
+ path += nd;
+ if (*path)
+ path++;
+ while (nd > 1) {
+ if (cp > pcopy + 1) {
+ cp--;
+ while (cp > pcopy) {
+ if (IS_PATH_SEP(*(cp - 1)))
+ break;
+ cp--;
+ }
+ }
+ else
+ break;
+ nd--;
+ }
+ }
+ else
+ ch = *cp++ = *path++;
+ }
+ else
+ ch = *cp++ = *path++;
+ }
+ *cp = '\0';
+ /* Duplicate the final path
+ */
+ return pcopy;
+}
+
+/* Calculate the absolute path by merging the current
+ * working directory in case of relative paths.
+ * Function doesn't resolve symbolic links.
+ */
+char *acr_GetAbsolutePath(JNIEnv *_E, const char *path)
+{
+ char pcopy[UCPATH_MAX];
+ char *cp;
+
+ cp = _abs_path(pcopy, UCPATH_MAX, path);
+ if (!cp) {
+ ACR_THROW_IO_ERRNO();
+ return NULL;
+ }
+ else {
+ /* Duplicate the final path
+ */
+ return ACR_StrdupA(_E, THROW_FMARK, cp);
+ }
+}
+
+ACR_IO_EXPORT_DECLARE(void, Path, init0)(ACR_JNISTDARGS,
+ jintArray p)
+{
+ jint ia[4];
+
+ UNREFERENCED_O;
+
+ ia[0] = '/';
+ ia[1] = ':';
+ ia[2] = PATH_MAX - 1;
+ ia[3] = 1;
+ (*_E)->SetIntArrayRegion(_E, p, 0, 4, &ia[0]);
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Path, canon0)(ACR_JNISTDARGS, jstring path)
+{
+ int rc = 0;
+ jstring rv = NULL;
+
+ UNREFERENCED_O;
+ WITH_CSTR(path) {
+ char pcopy[UCPATH_MAX];
+ char *abs;
+ if ((abs = _abs_path(pcopy, UCPATH_MAX, J2S(path))))
+ rv = ACR_NewJavaStringA(_E, abs);
+ else
+ rc = ACR_GET_OS_ERROR();
+ } END_WITH_CSTR(path);
+
+ ACR_THROW_IO_IF_ERR(rc);
+ return rv;
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Path, merge0)(ACR_JNISTDARGS,
+ jstring root,
+ jstring path)
+{
+ int rc = 0;
+ jstring rv = NULL;
+
+ 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);
+ else
+ rc = ACR_GET_OS_ERROR();
+ } END_WITH_CSTR(path);
+ } END_WITH_CSTR(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_CSTR(root) {
+ WITH_CSTR(path) {
+ char pcopy[UCPATH_MAX];
+ char merge[UCPATH_MAX];
+ char *abs;
+ /* Normalize path */
+ if ((abs = _abs_path(pcopy, UCPATH_MAX, J2S(path)))) {
+ /* Prepend root */
+ strlcpy(merge, J2S(root), UCPATH_MAX);
+ strlcat(merge, "/", UCPATH_MAX);
+ strlcat(merge, abs, UCPATH_MAX);
+ rv = ACR_NewJavaStringA(_E, merge);
+ }
+ else
+ rc = ACR_GET_OS_ERROR();
+ } END_WITH_CSTR(path);
+ } END_WITH_CSTR(root);
+
+ ACR_THROW_IO_IF_ERR(rc);
+ return rv;
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Path, normal0)(ACR_JNISTDARGS, jstring path)
+{
+ int rc = 0;
+ jstring rv = NULL;
+
+ UNREFERENCED_O;
+ WITH_CSTR(path) {
+ char pcopy[UCPATH_MAX];
+ char *rel;
+ if ((rel = _rel_path(pcopy, UCPATH_MAX, J2S(path))))
+ rv = ACR_NewJavaStringA(_E, rel);
+ else
+ rc = ACR_GET_OS_ERROR();
+ } END_WITH_CSTR(path);
+
+ ACR_THROW_IO_IF_ERR(rc);
+ return rv;
+}
+
+ACR_IO_EXPORT_DECLARE(jstring, Path, native0)(ACR_JNISTDARGS, jstring path)
+{
+ /* On unix the Path is native path
+ */
+ return path;
+}
+
+ACR_IO_EXPORT_DECLARE(jint, Path, compare0)(ACR_JNISTDARGS,
+ jstring path,
+ jstring other)
+{
+ int rc = 1;
+
+ UNREFERENCED_O;
+ WITH_CSTR(path) {
+ WITH_CSTR(other) {
+ rc = strcmp(J2S(path), J2S(other));
+ } END_WITH_CSTR(other);
+ } END_WITH_CSTR(path);
+
+ return rc;
+}
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/unix/path.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c
URL: http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c?rev=828002&r1=828001&r2=828002&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/uutils.c Wed Oct 21 13:05:01 2009
@@ -206,70 +206,3 @@
arr[i] = NULL;
return arr;
}
-
-#define IS_PATH_SEP(C) ((C) == '/' || (C) == '\0')
-/* Calculate the absolute path by merging the current
- * working directory in case of relative paths.
- * Function doesn't resolve symbolic links.
- */
-char *acr_GetAbsolutePath(JNIEnv *_E, const char *path)
-{
- char pcopy[PATH_MAX * 2];
- char *cp;
- int ch = '/';
-
- if (*path == '/' && !strstr(path, "./")) {
- /* Already an absolute path
- */
- return ACR_StrdupA(_E, THROW_FMARK, path);
- }
- if (!IS_PATH_SEP(*path)) {
- if (!getcwd(pcopy, PATH_MAX)) {
- ACR_THROW_IO_ERRNO();
- return NULL;
- }
- strlcat(pcopy, "/", PATH_MAX * 2);
- strlcat(pcopy, path, PATH_MAX * 2);
- }
- else
- strlcpy(pcopy, path, PATH_MAX * 2);
-
- path = cp = pcopy;
- while (*path) {
- if (IS_PATH_SEP(ch) && *path == '.') {
- size_t nd = 0;
- while (path[nd] == '.')
- nd++;
- if (nd > 2) {
- ACR_THROW_IO_IF_ERR(ACR_EINVAL);
- return NULL;
- }
- if (IS_PATH_SEP(path[nd])) {
- path += nd;
- if (*path)
- path++;
- while (nd > 1) {
- if (cp > pcopy + 1) {
- cp--;
- while (cp > pcopy) {
- if (IS_PATH_SEP(*(cp - 1)))
- break;
- cp--;
- }
- }
- else
- break;
- nd--;
- }
- }
- else
- ch = *cp++ = *path++;
- }
- else
- ch = *cp++ = *path++;
- }
- *cp = '\0';
- /* Duplicate the final path
- */
- return ACR_StrdupA(_E, THROW_FMARK, pcopy);
-}
Added: 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=828002&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c Wed Oct 21 13:05:01 2009
@@ -0,0 +1,204 @@
+/* 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.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#define ACR_WANT_LATE_DLL
+#include "acr_arch.h"
+#include "acr_error.h"
+#include "acr_memory.h"
+#include "acr_port.h"
+#include "acr_string.h"
+#include "acr_descriptor.h"
+#include "acr_file.h"
+
+/**
+ * Win32 file path functions
+ *
+ */
+
+#define NON_UNC_PATH_LENGTH 248
+/*
+ * 1. Remove \\?\ prefix
+ * 2. Replace UNC\ with \\
+ */
+static __inline wchar_t *NO2UNC(wchar_t *fname)
+{
+ if (wcsncmp(fname, L"\\\\?\\", 4) == 0) {
+ fname += 4;
+ if (wcsncmp(fname, L"UNC\\", 4) == 0) {
+ fname += 2;
+ *fname = L'\\';
+ }
+ else if (wcsncmp(fname, L"UN\\\\", 4) == 0) {
+ /* Already modified in-place.
+ */
+ fname += 2;
+ }
+ }
+ return fname;
+}
+
+static __inline void FS2BS(wchar_t *path)
+{
+ while (*path) {
+ if (*path == L'/')
+ *path = L'\\';
+ path++;
+ }
+}
+
+ACR_DECLARE(wchar_t *) ACR_GetJavaNativePathW(JNIEnv *_E, jstring str, wchar_t *b)
+{
+ size_t srclen;
+ size_t retlen;
+ const jchar *sr;
+ wchar_t *rv = NULL;
+ wchar_t *retstr;
+ wchar_t *srcstr;
+
+ if (!str) {
+ return NULL;
+ }
+ if ((*_E)->EnsureLocalCapacity(_E, 2) < 0) {
+ /* JNI out of memory error */
+ return NULL;
+ }
+ retlen = srclen = (size_t)(*_E)->GetStringLength(_E, str);
+ if (b && srclen < (ACR_MBUFF_LEN - 8))
+ rv = b;
+ else {
+ rv = ACR_MALLOC(wchar_t, srclen + 9);
+ if (!rv) {
+ /* Exception has already neen throw from ACR_Malloc
+ */
+ return NULL;
+ }
+ }
+ srcstr = sr = (*_E)->GetStringCritical(_E, str, NULL);
+ if (!srcstr) {
+ if (rv != b)
+ x_free(rv);
+ return NULL;
+ }
+ else {
+ retstr = rv;
+ if (srclen > NON_UNC_PATH_LENGTH) {
+ if (srcstr[1] == L':' && (srcstr[2] == L'/' || srcstr[2] == L'\\')) {
+ 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
+ */
+ 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;
+ }
+ }
+
+ memcpy(retstr, srcstr, srclen * sizeof(wchar_t));
+ }
+ rv[retlen] = L'\0';
+ FS2BS(retstr);
+ (*_E)->ReleaseStringCritical(_E, str, sr);
+ return rv;
+}
+
+ACR_DECLARE(jstring) ACR_NewJavaNativePathW(JNIEnv *_E, const wchar_t *s)
+{
+ jstring r = NULL;
+ if (s) {
+ wchar_t *retstr;
+ wchar_t *srcstr;
+ wchar_t buff[ACR_MBUFF_SIZ];
+ size_t retlen = wcslen(s);
+
+ if (l > ACR_MBUFF_LEN) {
+ srcstr = ACR_StrdupW(_E, THROW_FMARK, s);
+ if (!srcstr)
+ return NULL;
+ else {
+ wcscpy(buff, s);
+ srcstr = buff;
+ }
+ retstr = 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'\\') {
+ retstr[0] = '\\';
+ retstr[1] = '\\';
+ retstr += 2;
+ retlen -= 6;
+ }
+ else {
+ retstr += 4;
+ retlen -= 4;
+ }
+ }
+ /* 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
+ */
+ for (; *retstr; retstr++) {
+ if (*retstr == '\\')
+ *retstr = '/';
+ }
+ r = (*_E)->NewString(_E, (const jchar *)s, (jsize)retlen);
+ }
+ return r;
+}
Propchange: commons/sandbox/runtime/trunk/src/main/native/os/win32/path.c
------------------------------------------------------------------------------
svn:eol-style = native
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=828002&r1=828001&r2=828002&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 Wed Oct 21 13:05:01 2009
@@ -202,7 +202,7 @@
User u = User.getEffective();
- f.setFileOwner(u);
+ f.setOwner(u);
f.delete();
}
@@ -213,7 +213,7 @@
f.createNewFile();
Group g = Group.getEffective();
- f.setFileOwner(g);
+ f.setOwner(g);
f.delete();
}
@@ -327,5 +327,25 @@
f2.delete();
}
+ public void testPath()
+ throws Exception
+ {
+ String [] paths = {
+ "/",
+ "\\\\",
+ "foo/",
+ "/foo/",
+ "/foo/bar",
+ "c:/foo/../../bar",
+ "foo/../bar",
+ "foo/../../../bar",
+ "/foo/../bar",
+ "/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());
+ }
+ }
}