From f40475404235a392b16bb7db048fc18c56af3604 Mon Sep 17 00:00:00 2001 From: Bryce McKinlay Date: Sun, 1 Apr 2001 11:16:40 +0000 Subject: [PATCH] 1.3-Compliant Implementation of java.io.File. * java/lang/natSystem.cc (init_properties): Get "file.separator", "path.separator", and "java.io.tmpdir" from the File class, instead of setting them explicitly. * java/io/File.java: Do not canonicalize paths for security manager checks. Call init_native() from static initializer. Do not pass path argument to native methods. New native method declarations. Some security manager checks moved to checkWrite(). (equals): Check file system case sensitivity and act appropriatly. (hashCode): Likewise. (isHidden): New method implemented. (performList): Changed prototype. Now takes a class argument specifying the class of the returned array: Strings or File objects. Also added FileFilter argument. (listFiles): New variants with "File" return type implemented. (createTempFile): Use createNewFile(). Use maxPathLen. (setReadOnly): New method implemented. (listRoots): Likewise. (compareTo): Likewise. (setLastModified): Likewise. (checkWrite): New method. (setPath): Removed. * java/io/natFile.cc: Various functions no longer take canonical path argument. (stat): Handle ISHIDDEN query. (isAbsolute): Remove WIN32 cruft. (performList): New arguments. Handle returning either File[] or String[] arrays. Check with FileFilter or FilenameFilter arguments as appropriate. Use an ArrayList, not a Vector, for the temporary list. (performSetReadOnly): New method implemented. (performListRoots): Likewise. (performSetLastModified): Likewise. (performCreate): Likewise. (init_native): New initialization function. * java/io/natFileWin32.cc: Various functions no longer take canonical path argument. (stat): Add FIXME about ISHIDDEN query. (performList): New arguments. Handle returning either File[] or String[] arrays. Check with FileFilter or FilenameFilter arguments as appropriate. Use an ArrayList, not a Vector, for the temporary list. (performSetReadOnly): New. Stubbed. (performListRoots): Likewise. (performSetLastModified): Likewise. (performCreate): Likewise. (init_native) New initialization function. * configure.in: Check for utime() and chmod(). * configure: Rebuilt. * include/config.h.in: Rebuilt. Resolves PR libgcj/1759. From-SVN: r40985 --- libjava/ChangeLog | 53 +++++ libjava/configure | 192 ++++++++++--------- libjava/configure.in | 3 +- libjava/include/config.h.in | 12 +- libjava/java/io/File.java | 330 ++++++++++++++++++++------------ libjava/java/io/natFile.cc | 180 ++++++++++++----- libjava/java/io/natFileWin32.cc | 96 +++++++--- libjava/java/lang/natSystem.cc | 18 +- 8 files changed, 582 insertions(+), 302 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 103147bece5..84aacc9e969 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,56 @@ +2001-04-01 Bryce McKinlay + + 1.3-Compliant Implementation of java.io.File. + * java/lang/natSystem.cc (init_properties): Get "file.separator", + "path.separator", and "java.io.tmpdir" from the File class, instead + of setting them explicitly. + * java/io/File.java: Do not canonicalize paths for security manager + checks. Call init_native() from static initializer. Do not pass path + argument to native methods. New native method declarations. Some + security manager checks moved to checkWrite(). + (equals): Check file system case sensitivity and act appropriatly. + (hashCode): Likewise. + (isHidden): New method implemented. + (performList): Changed prototype. Now takes a class argument specifying + the class of the returned array: Strings or File objects. Also added + FileFilter argument. + (listFiles): New variants with "File" return type implemented. + (createTempFile): Use createNewFile(). Use maxPathLen. + (setReadOnly): New method implemented. + (listRoots): Likewise. + (compareTo): Likewise. + (setLastModified): Likewise. + (checkWrite): New method. + (setPath): Removed. + * java/io/natFile.cc: Various functions no longer take canonical path + argument. + (stat): Handle ISHIDDEN query. + (isAbsolute): Remove WIN32 cruft. + (performList): New arguments. Handle returning either File[] or String[] + arrays. Check with FileFilter or FilenameFilter arguments as + appropriate. Use an ArrayList, not a Vector, for the temporary list. + (performSetReadOnly): New method implemented. + (performListRoots): Likewise. + (performSetLastModified): Likewise. + (performCreate): Likewise. + (init_native): New initialization function. + * java/io/natFileWin32.cc: Various functions no longer take canonical + path argument. + (stat): Add FIXME about ISHIDDEN query. + (performList): New arguments. Handle returning either File[] or String[] + arrays. Check with FileFilter or FilenameFilter arguments as + appropriate. Use an ArrayList, not a Vector, for the temporary list. + (performSetReadOnly): New. Stubbed. + (performListRoots): Likewise. + (performSetLastModified): Likewise. + (performCreate): Likewise. + (init_native) New initialization function. + * configure.in: Check for utime() and chmod(). + * configure: Rebuilt. + * include/config.h.in: Rebuilt. + + Resolves PR libgcj/1759. + 2001-03-28 Richard Henderson IA-64 ABI Exception Handling: diff --git a/libjava/configure b/libjava/configure index 71dd1aba863..749b29253ec 100755 --- a/libjava/configure +++ b/libjava/configure @@ -3390,7 +3390,7 @@ else fi done - for ac_func in access stat mkdir rename rmdir unlink realpath + for ac_func in access stat mkdir rename rmdir unlink realpath utime chmod do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:3397: checking for $ac_func" >&5 @@ -5158,19 +5158,20 @@ EOF + echo $ac_n "checking for g++ -ffloat-store bug""... $ac_c" 1>&6 -echo "configure:5163: checking for g++ -ffloat-store bug" >&5 +echo "configure:5164: checking for g++ -ffloat-store bug" >&5 save_CFLAGS="$CFLAGS" CFLAGS="-x c++ -O2 -ffloat-store" cat > conftest.$ac_ext < int main() { ; return 0; } EOF -if { (eval echo configure:5174: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5175: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""no" 1>&6 else @@ -5190,17 +5191,17 @@ for ac_hdr in unistd.h bstring.h sys/time.h sys/types.h fcntl.h sys/ioctl.h sys/ do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5194: checking for $ac_hdr" >&5 +echo "configure:5195: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5204: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5205: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5230,17 +5231,17 @@ for ac_hdr in dirent.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5234: checking for $ac_hdr" >&5 +echo "configure:5235: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5244: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5245: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5268,12 +5269,12 @@ done echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:5272: checking for ANSI C header files" >&5 +echo "configure:5273: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -5281,7 +5282,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5285: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5286: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -5298,7 +5299,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -5316,7 +5317,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -5337,7 +5338,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -5348,7 +5349,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:5352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5353: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -5372,12 +5373,12 @@ EOF fi echo $ac_n "checking for ssize_t""... $ac_c" 1>&6 -echo "configure:5376: checking for ssize_t" >&5 +echo "configure:5377: checking for ssize_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5406,9 +5407,9 @@ fi echo $ac_n "checking for in_addr_t""... $ac_c" 1>&6 -echo "configure:5410: checking for in_addr_t" >&5 +echo "configure:5411: checking for in_addr_t" >&5 cat > conftest.$ac_ext < #if STDC_HEADERS @@ -5422,7 +5423,7 @@ int main() { in_addr_t foo; ; return 0; } EOF -if { (eval echo configure:5426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5427: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_IN_ADDR_T 1 @@ -5438,16 +5439,16 @@ fi rm -f conftest* echo $ac_n "checking whether struct ip_mreq is in netinet/in.h""... $ac_c" 1>&6 -echo "configure:5442: checking whether struct ip_mreq is in netinet/in.h" >&5 +echo "configure:5443: checking whether struct ip_mreq is in netinet/in.h" >&5 cat > conftest.$ac_ext < int main() { struct ip_mreq mreq; ; return 0; } EOF -if { (eval echo configure:5451: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5452: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_STRUCT_IP_MREQ 1 @@ -5463,16 +5464,16 @@ fi rm -f conftest* echo $ac_n "checking whether struct sockaddr_in6 is in netinet/in.h""... $ac_c" 1>&6 -echo "configure:5467: checking whether struct sockaddr_in6 is in netinet/in.h" >&5 +echo "configure:5468: checking whether struct sockaddr_in6 is in netinet/in.h" >&5 cat > conftest.$ac_ext < int main() { struct sockaddr_in6 addr6; ; return 0; } EOF -if { (eval echo configure:5476: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5477: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_INET6 1 @@ -5488,9 +5489,9 @@ fi rm -f conftest* echo $ac_n "checking for socklen_t in sys/socket.h""... $ac_c" 1>&6 -echo "configure:5492: checking for socklen_t in sys/socket.h" >&5 +echo "configure:5493: checking for socklen_t in sys/socket.h" >&5 cat > conftest.$ac_ext < #include @@ -5498,7 +5499,7 @@ int main() { socklen_t x = 5; ; return 0; } EOF -if { (eval echo configure:5502: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5503: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_SOCKLEN_T 1 @@ -5514,16 +5515,16 @@ fi rm -f conftest* echo $ac_n "checking for tm_gmtoff in struct tm""... $ac_c" 1>&6 -echo "configure:5518: checking for tm_gmtoff in struct tm" >&5 +echo "configure:5519: checking for tm_gmtoff in struct tm" >&5 cat > conftest.$ac_ext < int main() { struct tm tim; tim.tm_gmtoff = 0; ; return 0; } EOF -if { (eval echo configure:5527: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5528: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define STRUCT_TM_HAS_GMTOFF 1 @@ -5536,16 +5537,16 @@ else rm -rf conftest* echo "$ac_t""no" 1>&6 echo $ac_n "checking for global timezone variable""... $ac_c" 1>&6 -echo "configure:5540: checking for global timezone variable" >&5 +echo "configure:5541: checking for global timezone variable" >&5 cat > conftest.$ac_ext < int main() { long z2 = timezone; ; return 0; } EOF -if { (eval echo configure:5549: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5550: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_TIMEZONE 1 @@ -5565,19 +5566,19 @@ rm -f conftest* # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:5569: checking for working alloca.h" >&5 +echo "configure:5570: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:5581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5582: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -5598,12 +5599,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:5602: checking for alloca" >&5 +echo "configure:5603: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5636: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -5663,12 +5664,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:5667: checking whether alloca needs Cray hooks" >&5 +echo "configure:5668: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:5697: checking for $ac_func" >&5 +echo "configure:5698: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:5726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -5748,7 +5749,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:5752: checking stack direction for C alloca" >&5 +echo "configure:5753: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5756,7 +5757,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:5780: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -5802,7 +5803,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:5806: checking for $ac_word" >&5 +echo "configure:5807: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_PERL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5871,7 +5872,7 @@ fi # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 -echo "configure:5875: checking for X" >&5 +echo "configure:5876: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then @@ -5933,12 +5934,12 @@ if test "$ac_x_includes" = NO; then # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5942: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:5943: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6007,14 +6008,14 @@ if test "$ac_x_libraries" = NO; then ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. @@ -6120,17 +6121,17 @@ else case "`(uname -sr) 2>/dev/null`" in "SunOS 5"*) echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6 -echo "configure:6124: checking whether -R must be followed by a space" >&5 +echo "configure:6125: checking whether -R must be followed by a space" >&5 ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_nospace=yes else @@ -6146,14 +6147,14 @@ rm -f conftest* else LIBS="$ac_xsave_LIBS -R $x_libraries" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6158: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_R_space=yes else @@ -6185,7 +6186,7 @@ rm -f conftest* # libraries were built with DECnet support. And karl@cs.umb.edu says # the Alpha needs dnet_stub (dnet does not exist). echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6 -echo "configure:6189: checking for dnet_ntoa in -ldnet" >&5 +echo "configure:6190: checking for dnet_ntoa in -ldnet" >&5 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6193,7 +6194,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6209: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6226,7 +6227,7 @@ fi if test $ac_cv_lib_dnet_dnet_ntoa = no; then echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6 -echo "configure:6230: checking for dnet_ntoa in -ldnet_stub" >&5 +echo "configure:6231: checking for dnet_ntoa in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6234,7 +6235,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6274,12 +6275,12 @@ fi # The nsl library prevents programs from opening the X display # on Irix 5.2, according to dickey@clark.net. echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 -echo "configure:6278: checking for gethostbyname" >&5 +echo "configure:6279: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else @@ -6323,7 +6324,7 @@ fi if test $ac_cv_func_gethostbyname = no; then echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6 -echo "configure:6327: checking for gethostbyname in -lnsl" >&5 +echo "configure:6328: checking for gethostbyname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6331,7 +6332,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6347: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6372,12 +6373,12 @@ fi # -lsocket must be given before -lnsl if both are needed. # We assume that if connect needs -lnsl, so does gethostbyname. echo $ac_n "checking for connect""... $ac_c" 1>&6 -echo "configure:6376: checking for connect" >&5 +echo "configure:6377: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_connect=yes" else @@ -6421,7 +6422,7 @@ fi if test $ac_cv_func_connect = no; then echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6 -echo "configure:6425: checking for connect in -lsocket" >&5 +echo "configure:6426: checking for connect in -lsocket" >&5 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6429,7 +6430,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6464,12 +6465,12 @@ fi # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX. echo $ac_n "checking for remove""... $ac_c" 1>&6 -echo "configure:6468: checking for remove" >&5 +echo "configure:6469: checking for remove" >&5 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6497: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_remove=yes" else @@ -6513,7 +6514,7 @@ fi if test $ac_cv_func_remove = no; then echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6 -echo "configure:6517: checking for remove in -lposix" >&5 +echo "configure:6518: checking for remove in -lposix" >&5 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6521,7 +6522,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lposix $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6556,12 +6557,12 @@ fi # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. echo $ac_n "checking for shmat""... $ac_c" 1>&6 -echo "configure:6560: checking for shmat" >&5 +echo "configure:6561: checking for shmat" >&5 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_shmat=yes" else @@ -6605,7 +6606,7 @@ fi if test $ac_cv_func_shmat = no; then echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6 -echo "configure:6609: checking for shmat in -lipc" >&5 +echo "configure:6610: checking for shmat in -lipc" >&5 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6613,7 +6614,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lipc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6657,7 +6658,7 @@ fi # libraries we check for below, so use a different variable. # --interran@uluru.Stanford.EDU, kb@cs.umb.edu. echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6 -echo "configure:6661: checking for IceConnectionNumber in -lICE" >&5 +echo "configure:6662: checking for IceConnectionNumber in -lICE" >&5 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -6665,7 +6666,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lICE $X_EXTRA_LIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6681: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -6979,6 +6980,7 @@ s%@USE_LIBDIR_FALSE@%$USE_LIBDIR_FALSE%g s%@NEEDS_DATA_START_TRUE@%$NEEDS_DATA_START_TRUE%g s%@NEEDS_DATA_START_FALSE@%$NEEDS_DATA_START_FALSE%g s%@GCC_UNWIND_INCLUDE@%$GCC_UNWIND_INCLUDE%g +s%@GCJVERSION@%$GCJVERSION%g s%@AM_RUNTESTFLAGS@%$AM_RUNTESTFLAGS%g s%@ALLOCA@%$ALLOCA%g s%@PERL@%$PERL%g diff --git a/libjava/configure.in b/libjava/configure.in index 89bbe7fb198..4e00fce4ac0 100644 --- a/libjava/configure.in +++ b/libjava/configure.in @@ -431,7 +431,7 @@ if test -n "${with_cross_host}"; then else AC_CHECK_FUNCS(strerror ioctl select fstat open fsync sleep) AC_CHECK_FUNCS(gmtime_r localtime_r readdir_r getpwuid_r getcwd) - AC_CHECK_FUNCS(access stat mkdir rename rmdir unlink realpath) + AC_CHECK_FUNCS(access stat mkdir rename rmdir unlink realpath utime chmod) AC_CHECK_FUNCS(iconv nl_langinfo setlocale) AC_CHECK_FUNCS(inet_aton inet_addr, break) AC_CHECK_FUNCS(inet_pton uname inet_ntoa) @@ -669,6 +669,7 @@ changequote(<<,>>) gcjvers="`$GCJ -v 2>&1 | sed -n 's/^.*version \([^ ]*\).*$/\1/p'`" changequote([,]) AC_DEFINE_UNQUOTED(GCJVERSION, "$gcjvers") +AC_SUBST(GCJVERSION) AC_SUBST(AM_RUNTESTFLAGS) diff --git a/libjava/include/config.h.in b/libjava/include/config.h.in index a31dceadce4..b4cdf2468ea 100644 --- a/libjava/include/config.h.in +++ b/libjava/include/config.h.in @@ -135,9 +135,6 @@ getenv("GCJ_PROPERTIES"). */ #undef DISABLE_GETENV_PROPERTIES -/* Define if using setjmp/longjmp exceptions. */ -#undef SJLJ_EXCEPTIONS - /* Define if you have /proc/self/exe */ #undef HAVE_PROC_SELF_EXE @@ -167,6 +164,9 @@ /* Define if you have the backtrace function. */ #undef HAVE_BACKTRACE +/* Define if you have the chmod function. */ +#undef HAVE_CHMOD + /* Define if you have the execvp function. */ #undef HAVE_EXECVP @@ -287,6 +287,9 @@ /* Define if you have the unlink function. */ #undef HAVE_UNLINK +/* Define if you have the utime function. */ +#undef HAVE_UTIME + /* Define if you have the header file. */ #undef HAVE_ARPA_INET_H @@ -359,6 +362,9 @@ /* Version number of package */ #undef VERSION +/* Define if the compiler is configured for setjmp/longjmp exceptions. */ +#undef SJLJ_EXCEPTIONS + /* Required define if using POSIX threads */ #undef _REENTRANT diff --git a/libjava/java/io/File.java b/libjava/java/io/File.java index 5962641760d..8d987120161 100644 --- a/libjava/java/io/File.java +++ b/libjava/java/io/File.java @@ -1,6 +1,6 @@ // File.java - File name -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation This file is part of libgcj. @@ -21,42 +21,40 @@ import gnu.gcj.runtime.FileDeleter; /* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3 * "The Java Language Specification", ISBN 0-201-63451-1 - * Status: Complete to version 1.1; 1.2 functionality missing. - * A known bug: most calls to the security manager can generate - * IOException since we use the canonical path. + * Status: Complete to version 1.3. */ -public class File implements Serializable +public class File implements Serializable, Comparable { public boolean canRead () { - return access (checkRead (), READ); + checkRead(); + return access (READ); } public boolean canWrite () { - SecurityManager s = System.getSecurityManager(); - String p = safeCanonicalPath (); - // FIXME: it isn't entirely clear what to do if we can't find the - // canonical path. - if (p == null) - return false; - if (s != null) - s.checkWrite(p); - return access (p, WRITE); + checkWrite(); + return access (WRITE); } + + private native boolean performCreate() throws IOException; - private final native static boolean performDelete (String canon); + /** @since 1.2 */ + public boolean createNewFile() throws IOException + { + checkWrite(); + return performCreate(); + } + + private native boolean performDelete (); public boolean delete () { SecurityManager s = System.getSecurityManager(); - String p = safeCanonicalPath (); - // FIXME: what is right? - if (p == null) - return false; + String name = path; if (s != null) - s.checkDelete(p); - return performDelete (p); + s.checkDelete(path); + return performDelete (); } public boolean equals (Object obj) @@ -64,12 +62,16 @@ public class File implements Serializable if (! (obj instanceof File)) return false; File other = (File) obj; - return path.compareTo(other.path) == 0; + if (caseSensitive) + return (path.equals(other.path)); + else + return (path.equalsIgnoreCase(other.path)); } public boolean exists () { - return access (checkRead (), EXISTS); + checkRead(); + return access (EXISTS); } public File (String p) @@ -100,6 +102,7 @@ public class File implements Serializable this (dir == null ? null : dir.path, name); } + // FIXME ??? public String getAbsolutePath () { if (isAbsolute ()) @@ -107,6 +110,7 @@ public class File implements Serializable return System.getProperty("user.dir") + separatorChar + path; } + /** @since 1.2 */ public File getAbsoluteFile () throws IOException { return new File (getAbsolutePath()); @@ -114,6 +118,7 @@ public class File implements Serializable public native String getCanonicalPath () throws IOException; + /** @since 1.2 */ public File getCanonicalFile () throws IOException { return new File (getCanonicalPath()); @@ -133,6 +138,7 @@ public class File implements Serializable return path.substring(0, last); } + /** @since 1.2 */ public File getParentFile () { String parent = getParent (); @@ -146,42 +152,85 @@ public class File implements Serializable public int hashCode () { - // FIXME: test. - return path.hashCode(); + if (caseSensitive) + return (path.hashCode() ^ 1234321); + else + return (path.toLowerCase().hashCode() ^ 1234321); } public native boolean isAbsolute (); public boolean isDirectory () { - return stat (checkRead (), DIRECTORY); + checkRead(); + return stat (DIRECTORY); } public boolean isFile () { - return stat (checkRead (), ISFILE); + checkRead(); + return stat (ISFILE); + } + + /** @since 1.2 */ + public boolean isHidden() + { + checkRead(); + return stat (ISHIDDEN); } public long lastModified () { - return attr (checkRead (), MODIFIED); + checkRead(); + return attr (MODIFIED); } public long length () { - return attr (checkRead (), LENGTH); + checkRead(); + return attr (LENGTH); } + + private final native Object[] performList (FilenameFilter filter, + FileFilter fileFilter, + Class result_type); + + // Arguments for the performList function. Specifies whether we want + // File objects or path strings in the returned object array. + private final static int OBJECTS = 0; + private final static int STRINGS = 1; - private final native String[] performList (String canon, - FilenameFilter filter); public String[] list (FilenameFilter filter) { - return performList (checkRead (), filter); + checkRead(); + return (String[]) performList (filter, null, String.class); } public String[] list () { - return performList (checkRead (), null); + checkRead(); + return (String[]) performList (null, null, String.class); + } + + /** @since 1.2 */ + public File[] listFiles() + { + checkRead(); + return (File[]) performList (null, null, File.class); + } + + /** @since 1.2 */ + public File[] listFiles(FilenameFilter filter) + { + checkRead(); + return (File[]) performList (filter, null, File.class); + } + + /** @since 1.2 */ + public File[] listFiles(FileFilter filter) + { + checkRead(); + return (File[]) performList (null, filter, File.class); } public String toString () @@ -195,16 +244,10 @@ public class File implements Serializable } private final native boolean performMkdir (); + public boolean mkdir () { - SecurityManager s = System.getSecurityManager(); - if (s != null) - { - // NOTE: in theory we should use the canonical path. In - // practice, we can't compute the canonical path until we've - // made this completely. Lame. - s.checkWrite(path); - } + checkWrite(); return performMkdir (); } @@ -216,25 +259,17 @@ public class File implements Serializable String parent = x.getParent(); if (parent != null) { - x.setPath(parent); + x.path = parent; if (! mkdirs (x)) return false; - x.setPath(p); + x.path = p; } return x.mkdir(); } public boolean mkdirs () { - SecurityManager s = System.getSecurityManager(); - if (s != null) - { - // NOTE: in theory we should use the canonical path. In - // practice, we can't compute the canonical path until we've - // made this completely. Lame. - s.checkWrite(path); - } - + checkWrite(); if (isDirectory ()) return false; return mkdirs (new File (path)); @@ -245,6 +280,7 @@ public class File implements Serializable return Long.toString(counter++, Character.MAX_RADIX); } + /** @since 1.2 */ public static File createTempFile (String prefix, String suffix, File directory) throws IOException @@ -272,19 +308,16 @@ public class File implements Serializable if (suffix == null) suffix = ".tmp"; - // FIXME: filename length varies by architecture and filesystem. - int max_length = 255; - // Truncation rules. // `6' is the number of characters we generate. - if (prefix.length () + 6 + suffix.length () > max_length) + if (prefix.length () + 6 + suffix.length () > maxPathLen) { int suf_len = 0; if (suffix.charAt(0) == '.') suf_len = 4; suffix = suffix.substring(0, suf_len); - if (prefix.length () + 6 + suf_len > max_length) - prefix = prefix.substring(0, max_length - 6 - suf_len); + if (prefix.length () + 6 + suf_len > maxPathLen) + prefix = prefix.substring(0, maxPathLen - 6 - suf_len); } File f; @@ -298,27 +331,10 @@ public class File implements Serializable try { f = new File(directory, l); - if (f.exists()) - continue; - else - { - String af = f.getAbsolutePath (); - - // Check to see if we're allowed to write to it. - SecurityManager s = System.getSecurityManager(); - if (s != null) - s.checkWrite (af); - - // Now create the file. - FileDescriptor fd = - new FileDescriptor (af, - FileDescriptor.WRITE - | FileDescriptor.EXCL); - fd.close (); - return f; - } + if (f.createNewFile()) + return f; } - catch (IOException _) + catch (IOException ignored) { } } @@ -326,32 +342,119 @@ public class File implements Serializable throw new IOException ("cannot create temporary file"); } + private native boolean performSetReadOnly(); + + /** @since 1.2 */ + public boolean setReadOnly() + { + checkWrite(); + return performSetReadOnly(); + } + + private static native File[] performListRoots(); + + /** @since 1.2 */ + public static File[] listRoots() + { + File[] roots = performListRoots(); + + SecurityManager s = System.getSecurityManager(); + if (s != null) + { + // Only return roots to which the security manager permits read access. + int count = roots.length; + for (int i = 0; i < roots.length; i++) + { + try + { + s.checkRead(roots[i].path); + } + catch (SecurityException sx) + { + roots[i] = null; + count--; + } + } + if (count != roots.length) + { + File[] newRoots = new File[count]; + int k = 0; + for (int i=0; i < roots.length; i++) + { + if (roots[i] != null) + newRoots[k++] = roots[i]; + } + roots = newRoots; + } + } + return roots; + } + public static File createTempFile (String prefix, String suffix) throws IOException { return createTempFile (prefix, suffix, null); } - private final native boolean performRenameTo (File dest); + /** @since 1.2 */ + public int compareTo(File other) + { + if (caseSensitive) + return path.compareTo (other.path); + else + return path.compareToIgnoreCase (other.path); + } + + /** @since 1.2 */ + public int compareTo(Object o) + { + File other = (File) o; + return compareTo (other); + } + + private native boolean performRenameTo (File dest); public boolean renameTo (File dest) { SecurityManager s = System.getSecurityManager(); + String sname = getName(); + String dname = dest.getName(); if (s != null) { - // FIXME: JCL doesn't specify which path to check. We check the - // source since we can canonicalize it. - s.checkWrite(safeCanonicalPath()); + s.checkWrite(sname); + s.checkWrite(dname); } return performRenameTo (dest); } - public static final String pathSeparator - = System.getProperty("path.separator"); - public static final char pathSeparatorChar = pathSeparator.charAt(0); - public static final String separator = System.getProperty("file.separator"); - public static final char separatorChar = separator.charAt(0); + private native boolean performSetLastModified(long time); + + /** @since 1.2 */ + public boolean setLastModified(long time) + { + checkWrite(); + return performSetLastModified(time); + } - private static final String tmpdir = System.getProperty("java.io.tmpdir"); + public static final String separator = null; + public static final String pathSeparator = null; + static final String tmpdir = null; + static int maxPathLen; + static boolean caseSensitive; + + public static final char separatorChar; + public static final char pathSeparatorChar; + + static + { + init_native(); + pathSeparatorChar = pathSeparator.charAt(0); + separatorChar = separator.charAt(0); + } + + // Native function called at class initialization. This should should + // set the separator, pathSeparator, tmpdir, maxPathLen, and caseSensitive + // variables. + private static native void init_native(); // The path. private String path; @@ -360,41 +463,27 @@ public class File implements Serializable // value randomly to try to avoid clashes with other VMs. private static long counter = Double.doubleToLongBits (Math.random ()); - // mkdirs() uses this to avoid repeated allocations. - private final void setPath (String n) - { - path = n; - } - - - private final String checkRead () + private void checkWrite () { SecurityManager s = System.getSecurityManager(); - String p = safeCanonicalPath (); - if (p == null) - return null; if (s != null) - s.checkRead(p); - return p; + s.checkWrite(path); } - // Return canonical path, or null. - private final String safeCanonicalPath () + private void checkRead () { - String p = null; - try - { - p = getCanonicalPath (); - } - catch (IOException x) - { - // Nothing. - } - return p; + SecurityManager s = System.getSecurityManager(); + if (s != null) + s.checkRead(path); } - // Add this File to the set of files to be deleted upon normal - // termination. + /** + * Add this File to the set of files to be deleted upon normal + * termination. + * + * @since 1.2 + */ + // FIXME: This should use the ShutdownHook API once we implement that. public void deleteOnExit () { SecurityManager sm = System.getSecurityManager (); @@ -430,14 +519,15 @@ public class File implements Serializable // QUERY arguments to stat function. private final static int DIRECTORY = 0; private final static int ISFILE = 1; + private final static int ISHIDDEN = 2; // QUERY arguments to attr function. private final static int MODIFIED = 0; private final static int LENGTH = 1; - - private final native long attr (String p, int query); - private final native boolean access (String p, int query); - private final native boolean stat (String p, int query); + + private final native long attr (int query); + private final native boolean access (int query); + private final native boolean stat (int query); private static final long serialVersionUID = 301077366599181567L; } diff --git a/libjava/java/io/natFile.cc b/libjava/java/io/natFile.cc index 9fc55b2a808..e0f27b9dcce 100644 --- a/libjava/java/io/natFile.cc +++ b/libjava/java/io/natFile.cc @@ -1,6 +1,6 @@ -// natFile.cc - Native part of File class. +// natFile.cc - Native part of File class for POSIX. -/* Copyright (C) 1998, 1999, 2000 Free Software Foundation +/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation This file is part of libgcj. @@ -24,23 +24,23 @@ details. */ #include #endif #include +#include #include #include #include #include -#include +#include #include #include +#include #include jboolean -java::io::File::access (jstring canon, jint query) +java::io::File::access (jint query) { - if (! canon) - return false; char buf[MAXPATHLEN]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; JvAssert (query == READ || query == WRITE || query == EXISTS); @@ -59,15 +59,16 @@ java::io::File::access (jstring canon, jint query) } jboolean -java::io::File::stat (jstring canon, jint query) +java::io::File::stat (jint query) { - if (! canon) - return false; char buf[MAXPATHLEN]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; + if (query == ISHIDDEN) + return (getName()->charAt(0) == '.'); + #ifdef HAVE_STAT struct stat sb; if (::stat (buf, &sb)) @@ -82,13 +83,10 @@ java::io::File::stat (jstring canon, jint query) } jlong -java::io::File::attr (jstring canon, jint query) +java::io::File::attr (jint query) { - if (! canon) - return false; - char buf[MAXPATHLEN]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; @@ -99,8 +97,6 @@ java::io::File::attr (jstring canon, jint query) return 0; JvAssert (query == MODIFIED || query == LENGTH); - // FIXME: time computation is very POSIX-specific -- POSIX and Java - // have the same Epoch. return query == MODIFIED ? (jlong)sb.st_mtime * 1000 : sb.st_size; #else // There's no good choice here. @@ -131,23 +127,7 @@ java::io::File::getCanonicalPath (void) jboolean java::io::File::isAbsolute (void) { - // FIXME: cpp define name. - // FIXME: cygwin. -#ifdef WIN32 - if (path->charAt(0) == '/' || path->charAt(0) == '\\') - return true; - if (path->length() < 3) - return false; - // Hard-code A-Za-z because Windows (I think) can't use non-ASCII - // letters as drive names. - if ((path->charAt(0) < 'a' || path->charAt(0) > 'z') - && (path->charAt(0) < 'A' || path->charAt(0) > 'Z')) - return false; - return (path->charAt(1) == ':' - && (path->charAt(2) == '/' || path->charAt(2) == '\\')); -#else return path->charAt(0) == '/'; -#endif } #ifdef HAVE_DIRENT_H @@ -173,15 +153,14 @@ get_entry (DIR *dir, struct dirent *) #endif /* defined(__JV_POSIX_THREADS__) && defined(HAVE_READDIR_R) */ #endif /* HAVE_DIRENT_H */ -jstringArray -java::io::File::performList (jstring canon, FilenameFilter *filter) +jobjectArray +java::io::File::performList (java::io::FilenameFilter *filter, + java::io::FileFilter *fileFilter, + java::lang::Class *result_type) { - if (! canon) - return NULL; - #ifdef HAVE_DIRENT_H char buf[MAXPATHLEN]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; @@ -189,26 +168,37 @@ java::io::File::performList (jstring canon, FilenameFilter *filter) if (! dir) return NULL; - java::util::Vector *vec = new java::util::Vector (); + java::util::ArrayList *list = new java::util::ArrayList (); struct dirent *d, d2; while ((d = get_entry (dir, &d2)) != NULL) { - if (! strcmp (d->d_name, ".") || ! strcmp (d->d_name, "..")) + // Omit "." and "..". + if (d->d_name[0] == '.' + && (d->d_name[1] == '\0' + || (d->d_name[1] == '.' && d->d_name[2] == '\0'))) continue; jstring name = JvNewStringUTF (d->d_name); if (filter && ! filter->accept(this, name)) continue; + + if (result_type == &java::io::File::class$) + { + java::io::File *file = new java::io::File (this, name); + if (fileFilter && ! fileFilter->accept(file)) + continue; - vec->addElement(name); + list->add(file); + } + else + list->add(name); } closedir (dir); - jobjectArray ret = JvNewObjectArray (vec->size(), canon->getClass(), - NULL); - vec->copyInto(ret); - return reinterpret_cast (ret); + jobjectArray ret = JvNewObjectArray (list->size(), result_type, NULL); + list->toArray(ret); + return ret; #else /* HAVE_DIRENT_H */ return NULL; #endif /* HAVE_DIRENT_H */ @@ -229,6 +219,42 @@ java::io::File::performMkdir (void) #endif } +jboolean +java::io::File::performSetReadOnly (void) +{ + char buf[MAXPATHLEN]; + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); + // FIXME? + buf[total] = '\0'; + +#ifdef HAVE_STAT && HAVE_CHMOD + struct stat sb; + if (::stat (buf, &sb)) + return false; + + if (::chmod(buf, sb.st_mode & 0555)) + return false; + return true; +#else + return false; +#endif +} + +static JArray *unixroot; + +JArray< ::java::io::File *>* +java::io::File::performListRoots () +{ + if (unixroot == NULL) + { + ::java::io::File *f = new ::java::io::File (JvNewStringLatin1 ("/")); + unixroot = reinterpret_cast *> + (JvNewObjectArray (1, &java::io::File::class$, f)); + elements (unixroot) [0] = f; + } + return unixroot; +} + jboolean java::io::File::performRenameTo (File *dest) { @@ -249,10 +275,52 @@ java::io::File::performRenameTo (File *dest) } jboolean -java::io::File::performDelete (jstring canon) +java::io::File::performSetLastModified (jlong time) +{ +#ifdef HAVE_UTIME + utimbuf tb; + + char buf[MAXPATHLEN]; + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); + // FIXME? + buf[total] = '\0'; + + tb.actime = time / 1000; + tb.modtime = time / 1000; + return ::utime (buf, &tb); +#else + return false; +#endif +} + +jboolean +java::io::File::performCreate (void) { char buf[MAXPATHLEN]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); + // FIXME? + buf[total] = '\0'; + + int fd = ::open (buf, O_CREAT | O_EXCL, 0644); + + if (fd < 0) + { + if (errno == EEXIST) + return false; + throw new IOException (JvNewStringLatin1 (strerror (errno))); + } + else + { + ::close (fd); + return true; + } +} + +jboolean +java::io::File::performDelete (void) +{ + char buf[MAXPATHLEN]; + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; @@ -266,3 +334,17 @@ java::io::File::performDelete (jstring canon) #endif // HAVE_UNLINK return false; } + +void +java::io::File::init_native () +{ + separator = JvNewStringLatin1 ("/"); + pathSeparator = JvNewStringLatin1 (":"); + + char *tmp = ::getenv("TMPDIR"); + if (! tmp) + tmp = "/tmp"; + tmpdir = JvNewStringLatin1 (tmp); + maxPathLen = MAXPATHLEN; + caseSensitive = true; +} diff --git a/libjava/java/io/natFileWin32.cc b/libjava/java/io/natFileWin32.cc index 95be487bbdd..2f0b8afcc75 100644 --- a/libjava/java/io/natFileWin32.cc +++ b/libjava/java/io/natFileWin32.cc @@ -1,6 +1,6 @@ -// natFileWin32.cc - Native part of File class. +// natFileWin32.cc - Native part of File class for Win32. -/* Copyright (C) 1998, 1999 Red Hat, Inc. +/* Copyright (C) 1998, 1999, 2001 Red Hat, Inc. This file is part of libgcj. @@ -25,12 +25,10 @@ details. */ #include jboolean -java::io::File::access (jstring canon, jint query) +java::io::File::access (jint query) { - if (! canon) - return false; char buf[MAX_PATH]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; @@ -48,15 +46,15 @@ java::io::File::access (jstring canon, jint query) } jboolean -java::io::File::stat (jstring canon, jint query) +java::io::File::stat (jint query) { - if (! canon) - return false; char buf[MAX_PATH]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; + // FIXME: Need to handle ISHIDDEN query. + JvAssert (query == DIRECTORY || query == ISFILE); DWORD attributes = GetFileAttributes (buf); @@ -70,12 +68,10 @@ java::io::File::stat (jstring canon, jint query) } jlong -java::io::File::attr (jstring canon, jint query) +java::io::File::attr (jint query) { - if (! canon) - return false; char buf[MAX_PATH]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; @@ -128,12 +124,12 @@ java::io::File::isAbsolute (void) } jstringArray -java::io::File::performList (jstring canon, FilenameFilter *filter) +java::io::File::performList (java::io::FilenameFilter *filter, + java::io::FileFilter *fileFilter, + java::lang::Class *result_type) { - if (! canon) - return NULL; char buf[MAX_PATH]; - jsize total = JvGetStringUTFRegion (canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion (path, 0, path->length(), buf); // FIXME? strcpy(&buf[total], "\\*.*"); @@ -142,16 +138,28 @@ java::io::File::performList (jstring canon, FilenameFilter *filter) if (handle == INVALID_HANDLE_VALUE) return NULL; - java::util::Vector *vec = new java::util::Vector (); + java::util::ArrayList *list = new java::util::ArrayList (); do { if (strcmp (data.cFileName, ".") && strcmp (data.cFileName, "..")) { jstring name = JvNewStringUTF (data.cFileName); - if (! filter || (filter && filter->accept(this, name))) - vec->addElement (name); - } + + if (filter && ! filter->accept(this, name)) + continue; + + if (result_type == &java::io::File::class$) + { + java::io::File *file = new java::io::File (this, name); + if (fileFilter && ! fileFilter->accept(file)) + continue; + + list->add(file); + } + else + list->add(name); + } } while (FindNextFile (handle, &data)); @@ -160,7 +168,7 @@ java::io::File::performList (jstring canon, FilenameFilter *filter) FindClose (handle); - jobjectArray ret = JvNewObjectArray (vec->size(), canon->getClass(), NULL); + jobjectArray ret = JvNewObjectArray (vec->size(), path->getClass(), NULL); vec->copyInto (ret); return reinterpret_cast (ret); } @@ -176,6 +184,20 @@ java::io::File::performMkdir (void) return (CreateDirectory(buf, NULL)) ? true : false; } +jboolean +java::io::File::performSetReadOnly (void) +{ + // PLEASE IMPLEMENT ME + return false; +} + +JArray< ::java::io::File *>* +java::io::File::performListRoots () +{ + // PLEASE IMPLEMENT ME + return NULL; +} + jboolean java::io::File::performRenameTo (File *dest) { @@ -192,10 +214,24 @@ java::io::File::performRenameTo (File *dest) } jboolean -java::io::File::performDelete (jstring canon) +java::io::File::performSetLastModified (jlong time) +{ + // PLEASE IMPLEMENT ME + return false; +} + +jboolean +java::io::File::performCreate (void) +{ + // PLEASE IMPLEMENT ME + return false; +} + +jboolean +java::io::File::performDelete () { char buf[MAX_PATH]; - jsize total = JvGetStringUTFRegion(canon, 0, canon->length(), buf); + jsize total = JvGetStringUTFRegion(path, 0, path->length(), buf); // FIXME? buf[total] = '\0'; @@ -208,3 +244,13 @@ java::io::File::performDelete (jstring canon) else return (DeleteFile (buf)) ? true : false; } + +void +java::io::File::init_native () +{ + separator = JvNewStringLatin1 ("\\"); + pathSeparator = JvNewStringLatin1 (";"); + tmpdir = JvNewStringLatin1 ("C:\\temp"); // FIXME? + maxPathLen = MAX_PATH; + caseSensitive = false; +} diff --git a/libjava/java/lang/natSystem.cc b/libjava/java/lang/natSystem.cc index abf62caae8a..ee1d9988ca7 100644 --- a/libjava/java/lang/natSystem.cc +++ b/libjava/java/lang/natSystem.cc @@ -55,6 +55,7 @@ details. */ #include #include #include +#include #include #include @@ -323,20 +324,19 @@ java::lang::System::init_properties (void) SET ("file.encoding", default_file_encoding); + JvInitClass (&java::io::File::class$); + newprops->put (JvNewStringLatin1 ("file.separator"), + java::io::File::separator); + newprops->put (JvNewStringLatin1 ("path.separator"), + java::io::File::pathSeparator); + newprops->put (JvNewStringLatin1 ("java.io.tmpdir"), + java::io::File::tmpdir); + #ifdef WIN32 - SET ("file.separator", "\\"); - SET ("path.separator", ";"); SET ("line.separator", "\r\n"); - SET ("java.io.tmpdir", "C:\\temp"); #else // Unix. - SET ("file.separator", "/"); - SET ("path.separator", ":"); SET ("line.separator", "\n"); - char *tmpdir = ::getenv("TMPDIR"); - if (! tmpdir) - tmpdir = "/tmp"; - SET ("java.io.tmpdir", tmpdir); #endif #ifdef HAVE_UNAME