diff options
Diffstat (limited to 'libjava/classpath/native/jni/java-io/java_io_VMFile.c')
-rw-r--r-- | libjava/classpath/native/jni/java-io/java_io_VMFile.c | 734 |
1 files changed, 734 insertions, 0 deletions
diff --git a/libjava/classpath/native/jni/java-io/java_io_VMFile.c b/libjava/classpath/native/jni/java-io/java_io_VMFile.c new file mode 100644 index 00000000000..b32c29477e0 --- /dev/null +++ b/libjava/classpath/native/jni/java-io/java_io_VMFile.c @@ -0,0 +1,734 @@ +/* java_io_VMFile.c - Native methods for java.io.File class + Copyright (C) 1998, 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + +/* do not move; needed here because of some macro definitions */ +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include <jni.h> +#include <jcl.h> + +#include "target_native.h" +#ifndef WITHOUT_FILESYSTEM +#include "target_native_file.h" +#endif +#include "target_native_math_int.h" + +#include "javaio.h" + +#include "java_io_VMFile.h" + +/*************************************************************************/ + +/* + * Method to create an empty file. + * + * Class: java_io_VMFile + * Method: create + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_create (JNIEnv * env, + jclass clazz __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int fd; + int result; + + filename = JCL_jstring_to_cstring (env, name); + if (filename == NULL) + { + return (0); + } + + TARGET_NATIVE_FILE_OPEN_CREATE (filename, fd, result); + if (result != TARGET_NATIVE_OK) + { + /* XXX ??? NYI */ + if (errno != EEXIST) + JCL_ThrowException (env, + "java/io/IOException", + TARGET_NATIVE_LAST_ERROR_STRING ()); + JCL_free_cstring (env, name, filename); + return (0); + } + TARGET_NATIVE_FILE_CLOSE (fd, result); + + JCL_free_cstring (env, name, filename); + return (1); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method checks to see if we have read permission on a file. + * + * Class: java_io_VMFile + * Method: canRead + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_canRead (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int fd; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (0); + } + + /* The lazy man's way out. We actually do open the file for reading + briefly to verify it can be done */ + TARGET_NATIVE_FILE_OPEN_READ (filename, fd, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + if (result != TARGET_NATIVE_OK) + { + return (0); + } + TARGET_NATIVE_FILE_CLOSE (fd, result); + + return (1); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method checks to see if we have write permission on a file. + * + * Class: java_io_VMFile + * Method: canWrite + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_canWrite (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int fd; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (0); + } + + /* The lazy man's way out. We actually do open the file for writing + briefly to verify it can be done */ + TARGET_NATIVE_FILE_OPEN_READWRITE (filename, fd, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + if (result != TARGET_NATIVE_OK) + { + return (0); + } + TARGET_NATIVE_FILE_CLOSE (fd, result); + + return (1); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method makes a file read only. + * + * Class: java_io_VMFile + * Method: setReadOnly + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_setReadOnly (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (0); + } + + TARGET_NATIVE_FILE_SET_MODE_READONLY (filename, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + + return ((result == TARGET_NATIVE_OK) ? 1 : 0); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method checks to see if a file exists. + * + * Class: java_io_VMFile + * Method: exists + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_exists (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (0); + } + + TARGET_NATIVE_FILE_EXISTS (filename, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + + return ((result == TARGET_NATIVE_OK) ? 1 : 0); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method checks to see if a file is a "plain" file; that is, not + * a directory, pipe, etc. + * + * Class: java_io_VMFile + * Method: isFile + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_isFile (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (0); + } + + TARGET_NATIVE_FILE_IS_FILE (filename, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + + return ((result == TARGET_NATIVE_OK) ? 1 : 0); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method checks to see if a file is a directory or not. + * + * Class: java_io_VMFile + * Method: isDirectory + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_isDirectory (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (0); + } + + TARGET_NATIVE_FILE_IS_DIRECTORY (filename, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + + return ((result == TARGET_NATIVE_OK) ? 1 : 0); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method returns the length of the file. + * + * Class: java_io_VMFile + * Method: length + * Signature: (Ljava/lang/String;)J + */ + +JNIEXPORT jlong JNICALL +Java_java_io_VMFile_length (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int tmpfd; + jlong length; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (TARGET_NATIVE_MATH_INT_INT64_CONST_0); + } + + /* open file for reading, get size and close file */ + TARGET_NATIVE_FILE_OPEN_READ (filename, tmpfd, result); + if (result != TARGET_NATIVE_OK) + { + return (TARGET_NATIVE_MATH_INT_INT64_CONST_0); + } + TARGET_NATIVE_FILE_SIZE (tmpfd, length, result); + if (result != TARGET_NATIVE_OK) + { + TARGET_NATIVE_FILE_CLOSE (tmpfd, result); + return (TARGET_NATIVE_MATH_INT_INT64_CONST_0); + } + TARGET_NATIVE_FILE_CLOSE (tmpfd, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + + return ((result == + TARGET_NATIVE_OK) ? length : TARGET_NATIVE_MATH_INT_INT64_CONST_0); +#else /* not WITHOUT_FILESYSTEM */ + return (TARGET_NATIVE_MATH_INT_INT64_CONST_0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method returns the modification date of the file. + * + * Class: java_io_VMFile + * Method: lastModified + * Signature: (Ljava/lang/String;)J + */ + +JNIEXPORT jlong JNICALL +Java_java_io_VMFile_lastModified (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + jlong mtime; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (TARGET_NATIVE_MATH_INT_INT64_CONST_0); + } + + TARGET_NATIVE_FILE_GET_LAST_MODIFIED (filename, mtime, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + + return ((result == + TARGET_NATIVE_OK) ? mtime : TARGET_NATIVE_MATH_INT_INT64_CONST_0); +#else /* not WITHOUT_FILESYSTEM */ + return (TARGET_NATIVE_MATH_INT_INT64_CONST_0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method sets the modification date of the file. + * + * Class: java_io_VMFile + * Method: setLastModified + * Signature: (Ljava/lang/String;J)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_setLastModified (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name, jlong newtime) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (0); + } + + TARGET_NATIVE_FILE_SET_LAST_MODIFIED (filename, newtime, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + + return ((result == TARGET_NATIVE_OK) ? 1 : 0); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method deletes a file (actually a name for a file - additional + * links could exist). + * + * Class: java_io_VMFile + * Method: delete + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_delete (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *filename; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + filename = (*env)->GetStringUTFChars (env, name, 0); + if (filename == NULL) + { + return (0); + } + + TARGET_NATIVE_FILE_DELETE (filename, result); + (*env)->ReleaseStringUTFChars (env, name, filename); + + return ((result == TARGET_NATIVE_OK) ? 1 : 0); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method creates a directory. + * + * Class: java_io_VMFile + * Method: mkdir + * Signature: (Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_mkdir (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const char *pathname; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + pathname = (*env)->GetStringUTFChars (env, name, 0); + if (pathname == NULL) + { + return (0); + } + + TARGET_NATIVE_FILE_MAKE_DIR (pathname, result); + (*env)->ReleaseStringUTFChars (env, name, pathname); + + return ((result == TARGET_NATIVE_OK) ? 1 : 0); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method renames a (link to a) file. + * + * Class: java_io_VMFile + * Method: renameTo + * Signature: (Ljava/lang/String;Ljava/lang/String;)Z + */ + +JNIEXPORT jboolean JNICALL +Java_java_io_VMFile_renameTo (JNIEnv * env, + jobject obj __attribute__ ((__unused__)), + jstring t, jstring d) +{ +#ifndef WITHOUT_FILESYSTEM + const char *old_filename, *new_filename; + int result; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + old_filename = (*env)->GetStringUTFChars (env, t, 0); + if (old_filename == NULL) + { + return (0); + } + + new_filename = (*env)->GetStringUTFChars (env, d, 0); + if (new_filename == NULL) + { + (*env)->ReleaseStringUTFChars (env, t, old_filename); + return (0); + } + + TARGET_NATIVE_FILE_RENAME (old_filename, new_filename, result); + (*env)->ReleaseStringUTFChars (env, d, new_filename); + (*env)->ReleaseStringUTFChars (env, t, old_filename); + + return ((result == TARGET_NATIVE_OK) ? 1 : 0); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} + +/*************************************************************************/ + +/* + * This method returns an array of String representing all the files + * in a directory except "." and "..". + * + * Class: java_io_VMFile + * Method: list + * Signature: (Ljava/lang/String;)[Ljava/lang/String; + */ + +JNIEXPORT jobjectArray JNICALL +Java_java_io_VMFile_list (JNIEnv * env, jobject obj + __attribute__ ((__unused__)), jstring name) +{ +#ifndef WITHOUT_FILESYSTEM + const int REALLOC_SIZE = 10; + + const char *dirname; + int result; + char **filelist; + void *handle; + const char *filename; + unsigned long int filelist_count, max_filelist_count; + char **tmp_filelist; + jclass str_clazz; + jobjectArray filearray; + unsigned long int i; + jstring str; + + /* Don't use the JCL convert function because it throws an exception + on failure */ + dirname = (*env)->GetStringUTFChars (env, name, 0); + if (dirname == NULL) + { + return (0); + } + + /* open directory for reading */ + TARGET_NATIVE_FILE_OPEN_DIR (dirname, handle, result); + + (*env)->ReleaseStringUTFChars (env, name, dirname); + + if (result != TARGET_NATIVE_OK) + { + return (0); + } + + /* allocate filelist */ + filelist = (char **) JCL_malloc (env, sizeof (char *) * REALLOC_SIZE); + if (filelist == NULL) + { + TARGET_NATIVE_FILE_CLOSE_DIR (handle, result); + return (0); + } + filelist_count = 0; + max_filelist_count = REALLOC_SIZE; + + /* read the files from the directory */ + TARGET_NATIVE_FILE_READ_DIR (handle, filename, result); + while (result == TARGET_NATIVE_OK) + { + if ((strcmp (filename, ".") != 0) && (strcmp (filename, "..") != 0)) + { + /* allocate more memory if necessary */ + if (filelist_count >= max_filelist_count) + { + tmp_filelist = (char **) JCL_realloc (env, + filelist, + (max_filelist_count + + REALLOC_SIZE) * + sizeof (char *)); + if (tmp_filelist == NULL) + { + for (i = 0; i < filelist_count; i++) + { + JCL_free (env, filelist[i]); + } + JCL_free (env, filelist); + TARGET_NATIVE_FILE_CLOSE_DIR (handle, result); + return (0); + } + filelist = tmp_filelist; + max_filelist_count += REALLOC_SIZE; + } + + /* save entry in list (avoid strdup, because it is not ANSI C, thus difficult to port) */ + filelist[filelist_count] = + (char *) JCL_malloc (env, strlen (filename) + 1); + assert (filelist[filelist_count] != NULL); + strcpy (filelist[filelist_count], filename); + filelist_count++; + } + + /* read next directory entry */ + TARGET_NATIVE_FILE_READ_DIR (handle, filename, result); + } + + /* close directory */ + TARGET_NATIVE_FILE_CLOSE_DIR (handle, result); + + /* put the list of files into a Java String array and return it */ + str_clazz = (*env)->FindClass (env, "java/lang/String"); + if (str_clazz == NULL) + { + for (i = 0; i < filelist_count; i++) + { + JCL_free (env, filelist[i]); + } + JCL_free (env, filelist); + return (0); + } + filearray = (*env)->NewObjectArray (env, filelist_count, str_clazz, 0); + if (filearray == NULL) + { + for (i = 0; i < filelist_count; i++) + { + JCL_free (env, filelist[i]); + } + JCL_free (env, filelist); + return (0); + } + for (i = 0; i < filelist_count; i++) + { + /* create new string */ + str = (*env)->NewStringUTF (env, filelist[i]); + if (str == NULL) + { + /* We don't clean up everything here, but if this failed, + something serious happened anyway */ + for (i = 0; i < filelist_count; i++) + { + JCL_free (env, filelist[i]); + } + JCL_free (env, filelist); + return (0); + } + + /* save into array */ + (*env)->SetObjectArrayElement (env, filearray, i, str); + + /* delete local reference */ + (*env)->DeleteLocalRef (env, str); + } + + /* free resources */ + for (i = 0; i < filelist_count; i++) + { + JCL_free (env, filelist[i]); + } + JCL_free (env, filelist); + + return (filearray); +#else /* not WITHOUT_FILESYSTEM */ + return (0); +#endif /* not WITHOUT_FILESYSTEM */ +} |