diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 279d50f0d82..7131ba77787 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,24 @@ +1999-05-12 Tom Tromey + + * include/javaprims.h: Updated namespace declarations. + * classes.pl (scan): Uniquify class list. + * Makefile.in, configure: Rebuilt. + * Makefile.am (nat_source_files): Added natConcreteProcess.cc. + (built_java_source_files): New macro. + (nat_headers): Added built_java_source_files. + (javao_files): Likewise. + (EXTRA_libgcj_la_SOURCES): Likewise. + (libgcj.zip): Create built class files. + ($(built_java_source_files:.java=.class)): New target. + (jv_convert_LDADD): Added -L$(here)/.libs. + * configure.in: Create links for ConcreteProcess.java and + natConcreteProcess.cc. + * java/lang/Runtime.java (exec): Create a ConcreteProcess. + * java/lang/natEcosProcess.cc: New file. + * java/lang/EcosProcess.java: New file. + * java/lang/PosixProcess.java: New file. + * java/lang/natPosixProcess.cc: New file. + 1999-05-12 Warren Levy * java/net/PlainSocketImpl.java: Corrected copyright & header comments. diff --git a/libjava/Makefile.am b/libjava/Makefile.am index 4a01079d8ba..82665dd7ba8 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -85,11 +85,12 @@ nat_files = $(nat_source_files:.cc=.lo) ## Objects from C sources in subdirs. c_files = $(c_source_files:.c=.lo) ## Objects from Java sources in subdirs. -javao_files = $(java_source_files:.java=.lo) +javao_files = $(java_source_files:.java=.lo) \ + $(built_java_source_files:.java=.lo) libgcj_la_SOURCES = prims.cc jni.cc exception.cc EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \ - $(c_source_files) $(java_source_files) + $(c_source_files) $(java_source_files) $(built_java_source_files) libgcj_la_DEPENDENCIES = libgcj.zip $(javao_files) $(nat_files) \ $(c_files) $(GCOBJS) $(THREADOBJS) libgcj_la_LIBADD = $(javao_files) $(nat_files) $(c_files) $(GCOBJS) \ @@ -106,6 +107,14 @@ libgcj_la_LDFLAGS = -rpath $(toolexeclibdir) \ ## hand-maintained headers. $(java_source_files:.java=.class): libgcj.zip +## FIXME: this isn't really correct. +$(built_java_source_files:.java=.class): $(built_java_source_files) +## This little nastiness is here so that the backquoted stuff in the +## GCJ definition can be correctly expanded, if required. + javac="$(JAVAC)"; \ + $$javac $(JCFLAGS) -classpath $(here):`cd $(srcdir) && /bin/pwd` \ + -d $(here) $? + ## We have the zip file depend on the java sources and not the class ## files, because we don't know the names of all the class files. ## FIXME: this method fails in a peculiar case: if libgcj.zip is @@ -113,6 +122,9 @@ $(java_source_files:.java=.class): libgcj.zip ## `make libgcj.zip' will not rebuilt foo.class. That's because ## libgcj.zip is not out-of-date with respect to foo.java. libgcj.zip: $(java_source_files) +## FIXME: this ought to depend on built_java_source_files, but right +## now it can't. Ugly. + $(MAKE) $(built_java_source_files:.java=.class) ## This little nastiness is here so that the backquoted stuff in the ## GCJ definition can be correctly expanded, if required. javac="$(JAVAC)"; cd $(srcdir); \ @@ -168,7 +180,8 @@ $(javao_files): %.lo: %.java $(GCJH) -classpath $(top_builddir) $(basename $<) ## Header files used when compiling some of the nat* files. -nat_headers = $(ordinary_java_source_files:.java=.h) +nat_headers = $(ordinary_java_source_files:.java=.h) \ + $(built_java_source_files:.java=.h) $(nat_headers): libgcj.zip @@ -268,8 +281,10 @@ jv_convert_LINK = $(LIBTOOL) --mode=link $(GCJ) $(JC1FLAGS) $(LDFLAGS) \ ## We explicitly link in the libraries we need. This way we don't ## need -nodefaultlibs, so we can still rely on gcj picking up the ## system libraries we need (via the specs file). +## We need the -L so that gcj can find libgcj with `-lgcj'. +## FIXME: should be _libs on some systems. jv_convert_LDADD = $(convert_source_files:.java=.lo) libgcj.la \ - $(GCLIBS) $(THREADLIBS) $(ZLIBS) + $(GCLIBS) $(THREADLIBS) $(ZLIBS) -L$(here)/.libs ## Depend on the spec file to make sure it is up to date before ## linking this program. jv_convert_DEPENDENCIES = $(convert_source_files:.java=.lo) \ @@ -411,6 +426,10 @@ java/awt/peer/WindowPeer.java # $(awt_java_source_files) +## Java files which are created by configure and thus are in the build +## directory. +built_java_source_files = java/lang/ConcreteProcess.java + ## List of all .java files to be compiled. Please keep this list ## alphabetical. Please put files from gnu/gcj/convert into ## convert_source_files. If the .java file has a hand-maintained @@ -679,6 +698,7 @@ java/io/natFile.cc \ java/io/natFileDescriptor.cc \ java/lang/natCharacter.cc \ java/lang/natClass.cc \ +java/lang/natConcreteProcess.cc \ java/lang/natDouble.cc \ java/lang/natFirstThread.cc \ java/lang/natFloat.cc \ diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 760fbc33e63..e45a5a97ef9 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -156,11 +156,13 @@ INCLUDES = -Iinclude -I$(top_srcdir)/include $(GCINCS) $(THREADINCS) $(EH_COMMON nat_files = $(nat_source_files:.cc=.lo) c_files = $(c_source_files:.c=.lo) -javao_files = $(java_source_files:.java=.lo) +javao_files = $(java_source_files:.java=.lo) \ + $(built_java_source_files:.java=.lo) + libgcj_la_SOURCES = prims.cc jni.cc exception.cc EXTRA_libgcj_la_SOURCES = boehm.cc nogc.cc posix-threads.cc no-threads.cc \ - $(c_source_files) $(java_source_files) + $(c_source_files) $(java_source_files) $(built_java_source_files) libgcj_la_DEPENDENCIES = libgcj.zip $(javao_files) $(nat_files) \ $(c_files) $(GCOBJS) $(THREADOBJS) @@ -177,7 +179,9 @@ CLEANFILES = libgcj.zip SUFFIXES = .class .java .h -nat_headers = $(ordinary_java_source_files:.java=.h) +nat_headers = $(ordinary_java_source_files:.java=.h) \ + $(built_java_source_files:.java=.h) + FTFRIEND = void JvRunMain (jclass klass, int argc, const char **argv) @@ -279,6 +283,8 @@ java/awt/peer/WindowPeer.java # $(awt_java_source_files) +built_java_source_files = java/lang/ConcreteProcess.java + ordinary_java_source_files = $(convert_source_files) \ gnu/gcj/text/BaseBreakIterator.java \ gnu/gcj/text/CharacterBreakIterator.java \ @@ -543,6 +549,7 @@ java/io/natFile.cc \ java/io/natFileDescriptor.cc \ java/lang/natCharacter.cc \ java/lang/natClass.cc \ +java/lang/natConcreteProcess.cc \ java/lang/natDouble.cc \ java/lang/natFirstThread.cc \ java/lang/natFloat.cc \ @@ -721,8 +728,9 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ .deps/java/lang/ClassNotFoundException.P \ .deps/java/lang/CloneNotSupportedException.P \ .deps/java/lang/Cloneable.P .deps/java/lang/Comparable.P \ -.deps/java/lang/Compiler.P .deps/java/lang/Double.P \ -.deps/java/lang/Error.P .deps/java/lang/Exception.P \ +.deps/java/lang/Compiler.P .deps/java/lang/ConcreteProcess.P \ +.deps/java/lang/Double.P .deps/java/lang/Error.P \ +.deps/java/lang/Exception.P \ .deps/java/lang/ExceptionInInitializerError.P \ .deps/java/lang/FirstThread.P .deps/java/lang/Float.P \ .deps/java/lang/IllegalAccessError.P \ @@ -1341,7 +1349,13 @@ maintainer-clean-generic clean mostlyclean distclean maintainer-clean $(java_source_files:.java=.class): libgcj.zip +$(built_java_source_files:.java=.class): $(built_java_source_files) + javac="$(JAVAC)"; \ + $$javac $(JCFLAGS) -classpath $(here):`cd $(srcdir) && /bin/pwd` \ + -d $(here) $? + libgcj.zip: $(java_source_files) + $(MAKE) $(built_java_source_files:.java=.class) javac="$(JAVAC)"; cd $(srcdir); \ $$javac $(JCFLAGS) -classpath $(here):`/bin/pwd` -d $(here) \ $(subst $(srcdir)/,,$?) diff --git a/libjava/classes.pl b/libjava/classes.pl index 4db80a08c2e..35da03ef1a0 100644 --- a/libjava/classes.pl +++ b/libjava/classes.pl @@ -36,7 +36,7 @@ sub scan { local ($dir, $indent) = @_; local (@subdirs) = (); - local (@classes) = (); + local (%classes) = (); local ($d) = new DirHandle $dir; local (*JFILE); @@ -72,7 +72,7 @@ sub scan # For now assume that class names start with upper # case letter. next unless /(class|interface) ([A-Z][A-Za-z0-9]+)/; - push (@classes, $2); + $classes{$2} = 1; } close (FILE); } @@ -86,7 +86,7 @@ sub scan print $spaces, "namespace ", $classname, "\n"; print $spaces, "{\n"; - foreach (sort @classes) + foreach (sort keys %classes) { print $spaces, " class ", $_, ";\n"; } diff --git a/libjava/configure b/libjava/configure index ef133ad9847..f0141ac58ab 100755 --- a/libjava/configure +++ b/libjava/configure @@ -2611,9 +2611,11 @@ fi case "$TARGET_ECOS" in no) FILE_DESCRIPTOR=natFileDescriptorPosix.cc + PROCESS=Posix ;; *) FILE_DESCRIPTOR=natFileDescriptorEcos.cc + PROCESS=Ecos cat >> confdefs.h <<\EOF #define ECOS 1 EOF @@ -2622,7 +2624,7 @@ EOF esac echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:2626: checking how to run the C preprocessor" >&5 +echo "configure:2628: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -2637,13 +2639,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2647: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2649: \"$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 : @@ -2654,13 +2656,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2664: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2666: \"$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 : @@ -2671,13 +2673,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2681: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2683: \"$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 : @@ -2702,7 +2704,7 @@ fi echo "$ac_t""$CPP" 1>&6 cat > conftest.$ac_ext < EOF @@ -2717,7 +2719,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2733,7 +2735,7 @@ rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2748,7 +2750,7 @@ fi rm -f conftest* cat > conftest.$ac_ext < EOF @@ -2767,6 +2769,10 @@ test -d java || mkdir java test -d java/io || mkdir java/io +test -d java/lang || mkdir java/lang + + + SYSTEMSPEC= @@ -2782,7 +2788,7 @@ ZLIBSPEC= libsubdir=.libs echo $ac_n "checking for garbage collector to use""... $ac_c" 1>&6 -echo "configure:2786: checking for garbage collector to use" >&5 +echo "configure:2792: checking for garbage collector to use" >&5 # Check whether --enable-java-gc or --disable-java-gc was given. if test "${enable_java_gc+set}" = set; then enableval="$enable_java_gc" @@ -2832,7 +2838,7 @@ esac echo $ac_n "checking for threads package to use""... $ac_c" 1>&6 -echo "configure:2836: checking for threads package to use" >&5 +echo "configure:2842: checking for threads package to use" >&5 # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" @@ -3024,12 +3030,12 @@ else for ac_func in strerror ioctl select open fsync sleep do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3028: checking for $ac_func" >&5 +echo "configure:3034: 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:3062: \"$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 @@ -3079,12 +3085,12 @@ done for ac_func in ctime_r ctime do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3083: checking for $ac_func" >&5 +echo "configure:3089: 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:3117: \"$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 @@ -3134,12 +3140,12 @@ done for ac_func in gmtime_r localtime_r readdir_r getpwuid_r do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3138: checking for $ac_func" >&5 +echo "configure:3144: 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:3172: \"$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 @@ -3189,12 +3195,12 @@ done for ac_func in access stat mkdir rename rmdir unlink realpath do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3193: checking for $ac_func" >&5 +echo "configure:3199: 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:3227: \"$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 @@ -3244,12 +3250,12 @@ done for ac_func in inet_aton inet_addr do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3248: checking for $ac_func" >&5 +echo "configure:3254: 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:3282: \"$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 @@ -3299,12 +3305,12 @@ done for ac_func in inet_pton uname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3303: checking for $ac_func" >&5 +echo "configure:3309: 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:3337: \"$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 @@ -3355,12 +3361,12 @@ done for ac_func in gethostbyname_r do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3359: checking for $ac_func" >&5 +echo "configure:3365: 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:3393: \"$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 @@ -3410,7 +3416,7 @@ EOF # We look for the one that returns `int'. # Hopefully this check is robust enough. cat > conftest.$ac_ext < EOF @@ -3434,12 +3440,12 @@ done for ac_func in gethostbyaddr_r do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3438: checking for $ac_func" >&5 +echo "configure:3444: 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:3472: \"$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 @@ -3489,7 +3495,7 @@ EOF # We look for the one that returns `int'. # Hopefully this check is robust enough. cat > conftest.$ac_ext < EOF @@ -3513,12 +3519,12 @@ done for ac_func in gethostname do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3517: checking for $ac_func" >&5 +echo "configure:3523: 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:3551: \"$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 @@ -3565,7 +3571,7 @@ EOF EOF cat > conftest.$ac_ext < EOF @@ -3592,12 +3598,12 @@ done for ac_func in pthread_mutexattr_settype pthread_mutexattr_setkind_np sched_yield do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3596: checking for $ac_func" >&5 +echo "configure:3602: 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:3630: \"$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 @@ -3651,12 +3657,12 @@ done for ac_func in gettimeofday time ftime do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3655: checking for $ac_func" >&5 +echo "configure:3661: 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:3689: \"$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 @@ -3712,12 +3718,12 @@ done for ac_func in memmove do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3716: checking for $ac_func" >&5 +echo "configure:3722: 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:3750: \"$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 @@ -3773,12 +3779,12 @@ done for ac_func in memcpy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3777: checking for $ac_func" >&5 +echo "configure:3783: 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:3811: \"$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 @@ -3849,7 +3855,7 @@ done #-------------------------------------------------------------------- echo $ac_n "checking for socket libraries""... $ac_c" 1>&6 -echo "configure:3853: checking for socket libraries" >&5 +echo "configure:3859: checking for socket libraries" >&5 if eval "test \"`echo '$''{'gcj_cv_lib_sockets'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3857,12 +3863,12 @@ else gcj_checkBoth=0 unset ac_cv_func_connect echo $ac_n "checking for connect""... $ac_c" 1>&6 -echo "configure:3861: checking for connect" >&5 +echo "configure:3867: 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:3895: \"$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 @@ -3908,7 +3914,7 @@ fi if test "$gcj_checkSocket" = 1; then unset ac_cv_func_connect echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 -echo "configure:3912: checking for main in -lsocket" >&5 +echo "configure:3918: checking for main in -lsocket" >&5 ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -3916,14 +3922,14 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:3933: \"$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 @@ -3950,12 +3956,12 @@ fi LIBS="$LIBS -lsocket -lnsl" unset ac_cv_func_accept echo $ac_n "checking for accept""... $ac_c" 1>&6 -echo "configure:3954: checking for accept" >&5 +echo "configure:3960: checking for accept" >&5 if eval "test \"`echo '$''{'ac_cv_func_accept'+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:3988: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_accept=yes" else @@ -4005,12 +4011,12 @@ fi gcj_oldLibs=$LIBS LIBS="$LIBS $gcj_cv_lib_sockets" echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 -echo "configure:4009: checking for gethostbyname" >&5 +echo "configure:4015: 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:4043: \"$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 @@ -4051,7 +4057,7 @@ if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6 -echo "configure:4055: checking for main in -lnsl" >&5 +echo "configure:4061: checking for main in -lnsl" >&5 ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4059,14 +4065,14 @@ 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:4076: \"$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 @@ -4098,7 +4104,7 @@ echo "$ac_t""$gcj_cv_lib_sockets" 1>&6 if test "$with_system_zlib" = yes; then echo $ac_n "checking for deflate in -lz""... $ac_c" 1>&6 -echo "configure:4102: checking for deflate in -lz" >&5 +echo "configure:4108: checking for deflate in -lz" >&5 ac_lib_var=`echo z'_'deflate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -4106,7 +4112,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lz $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4127: \"$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 @@ -4217,17 +4223,17 @@ for ac_hdr in unistd.h sys/time.h sys/types.h fcntl.h sys/ioctl.h sys/filio.h sy do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:4221: checking for $ac_hdr" >&5 +echo "configure:4227: 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:4231: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4237: \"$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* @@ -4257,17 +4263,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:4261: checking for $ac_hdr" >&5 +echo "configure:4267: 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:4271: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:4277: \"$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* @@ -4295,16 +4301,16 @@ done echo $ac_n "checking whether struct sockaddr_in6 is in netinet/in.h""... $ac_c" 1>&6 -echo "configure:4299: checking whether struct sockaddr_in6 is in netinet/in.h" >&5 +echo "configure:4305: 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:4308: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4314: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_INET6 1 @@ -4320,16 +4326,16 @@ fi rm -f conftest* echo $ac_n "checking for socklen_t in sys/socket.h""... $ac_c" 1>&6 -echo "configure:4324: checking for socklen_t in sys/socket.h" >&5 +echo "configure:4330: checking for socklen_t in sys/socket.h" >&5 cat > conftest.$ac_ext < int main() { socklen_t x = 5; ; return 0; } EOF -if { (eval echo configure:4333: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4339: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_SOCKLEN_T 1 @@ -4345,16 +4351,16 @@ fi rm -f conftest* echo $ac_n "checking for tm_gmtoff in struct tm""... $ac_c" 1>&6 -echo "configure:4349: checking for tm_gmtoff in struct tm" >&5 +echo "configure:4355: 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:4358: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4364: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define STRUCT_TM_HAS_GMTOFF 1 @@ -4367,16 +4373,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:4371: checking for global timezone variable" >&5 +echo "configure:4377: checking for global timezone variable" >&5 cat > conftest.$ac_ext < int main() { long z2 = timezone; ; return 0; } EOF -if { (eval echo configure:4380: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:4386: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF #define HAVE_TIMEZONE 1 @@ -4396,19 +4402,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:4400: checking for working alloca.h" >&5 +echo "configure:4406: 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:4412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:4418: \"$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 @@ -4429,12 +4435,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:4433: checking for alloca" >&5 +echo "configure:4439: 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:4472: \"$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 @@ -4494,12 +4500,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:4498: checking whether alloca needs Cray hooks" >&5 +echo "configure:4504: 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:4528: checking for $ac_func" >&5 +echo "configure:4534: 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:4562: \"$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 @@ -4579,7 +4585,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:4583: checking stack direction for C alloca" >&5 +echo "configure:4589: 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 @@ -4587,7 +4593,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:4616: \"$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 @@ -4633,7 +4639,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:4637: checking for $ac_word" >&5 +echo "configure:4643: 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 @@ -5106,8 +5112,8 @@ fi; done EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF diff --git a/libjava/configure.in b/libjava/configure.in index a564ae39614..e21053574fe 100644 --- a/libjava/configure.in +++ b/libjava/configure.in @@ -55,9 +55,11 @@ TARGET_ECOS="$with_ecos" case "$TARGET_ECOS" in no) FILE_DESCRIPTOR=natFileDescriptorPosix.cc + PROCESS=Posix ;; *) FILE_DESCRIPTOR=natFileDescriptorEcos.cc + PROCESS=Ecos AC_DEFINE(ECOS) ;; esac @@ -76,6 +78,11 @@ test -d java || mkdir java test -d java/io || mkdir java/io AC_LINK_FILES(java/io/$FILE_DESCRIPTOR, java/io/natFileDescriptor.cc) +dnl Likewise for ConcreteProcess.java and natConcreteProcess.cc. +test -d java/lang || mkdir java/lang +AC_LINK_FILES(java/lang/${PROCESS}Process.java, java/lang/ConcreteProcess.java) +AC_LINK_FILES(java/lang/nat${PROCESS}Process.cc, java/lang/natConcreteProcess.cc) + SYSTEMSPEC= AC_SUBST(SYSTEMSPEC) diff --git a/libjava/include/javaprims.h b/libjava/include/javaprims.h index 83c2cf9faeb..2f815d28c06 100644 --- a/libjava/include/javaprims.h +++ b/libjava/include/javaprims.h @@ -106,6 +106,7 @@ extern "Java" class Cloneable; class Comparable; class Compiler; + class ConcreteProcess; class Double; class Error; class Exception; @@ -161,7 +162,6 @@ extern "Java" class VerifyError; class VirtualMachineError; class Void; - namespace reflect { class AccessibleObject; @@ -197,6 +197,7 @@ extern "Java" class Observable; class Observer; class Properties; + class PropertyResourceBundle; class Random; class ResourceBundle; class SimpleTimeZone; @@ -206,7 +207,6 @@ extern "Java" class TooManyListenersException; class Vector; class VectorEnumeration; - namespace zip { class Adler32; @@ -214,11 +214,13 @@ extern "Java" class Checksum; class Deflater; class DeflaterOutputStream; + class InflaterInputStream; class ZipConstants; class ZipEntry; class ZipEnumeration; class ZipException; class ZipFile; + class ZipInputStream; class ZipOutputStream; }; }; diff --git a/libjava/java/lang/EcosProcess.java b/libjava/java/lang/EcosProcess.java new file mode 100644 index 00000000000..83449169a64 --- /dev/null +++ b/libjava/java/lang/EcosProcess.java @@ -0,0 +1,59 @@ +// EcosProcess.java - Subclass of Process for eCos systems. + +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package java.lang; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * @author Tom Tromey + * @date May 11, 1999 + */ + +// This is entirely internal to our implementation. + +// This file is copied to `ConcreteProcess.java' before compilation. +// Hence the class name apparently does not match the file name. +final class ConcreteProcess extends Process +{ + // See natEcosProcess.cc to understand why this is native. + public native void destroy (); + + public int exitValue () + { + return 0; + } + public InputStream getErrorStream () + { + return null; + } + + public InputStream getInputStream () + { + return null; + } + + public OutputStream getOutputStream () + { + return null; + } + + public int waitFor () throws InterruptedException + { + return 0; + } + + public ConcreteProcess (String[] progarray, String[] envp) throws IOException + { + throw new IOException ("eCos processes unimplemented"); + } +} diff --git a/libjava/java/lang/PosixProcess.java b/libjava/java/lang/PosixProcess.java new file mode 100644 index 00000000000..396287ad46d --- /dev/null +++ b/libjava/java/lang/PosixProcess.java @@ -0,0 +1,74 @@ +// PosixProcess.java - Subclass of Process for POSIX systems. + +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +package java.lang; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * @author Tom Tromey + * @date May 3, 1999 + */ + +// This is entirely internal to our implementation. + +// This file is copied to `ConcreteProcess.java' before compilation. +// Hence the class name apparently does not match the file name. +final class ConcreteProcess extends Process +{ + public native void destroy (); + public native int exitValue (); + + public InputStream getErrorStream () + { + return errorStream; + } + + public InputStream getInputStream () + { + return inputStream; + } + + public OutputStream getOutputStream () + { + return outputStream; + } + + public native int waitFor () throws InterruptedException; + + // This is used for actual initialization, as we can't write a + // native constructor. + public native void startProcess (String[] progarray, String[] envp) + throws IOException; + + // This file is copied to `ConcreteProcess.java' before + // compilation. Hence the constructor name apparently does not + // match the file name. + public ConcreteProcess (String[] progarray, String[] envp) throws IOException + { + startProcess (progarray, envp); + } + + // The process id. This is cast to a pid_t on the native side. + private long pid; + + // True when child has exited. + private boolean hasExited; + + // The exit status, if the child has exited. + private int status; + + // The streams. + private InputStream errorStream; + private InputStream inputStream; + private OutputStream outputStream; +} diff --git a/libjava/java/lang/Runtime.java b/libjava/java/lang/Runtime.java index 94e7770e7e8..62a7c181d9f 100644 --- a/libjava/java/lang/Runtime.java +++ b/libjava/java/lang/Runtime.java @@ -52,8 +52,7 @@ public class Runtime SecurityManager s = System.getSecurityManager(); if (s != null) s.checkExec(progarray[0]); - // FIXME. - return null; + return new ConcreteProcess (progarray, envp); } private final static void checkExit (int status) diff --git a/libjava/java/lang/natEcosProcess.cc b/libjava/java/lang/natEcosProcess.cc new file mode 100644 index 00000000000..774a6977aac --- /dev/null +++ b/libjava/java/lang/natEcosProcess.cc @@ -0,0 +1,25 @@ +// natEcosProcess.cc - Native side of eCos processes. + +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +// The configury system needs this file to exist, since we can't +// really conditionally link files (an autoconf bug). To avoid having +// an empty translation unit, we make a single method native. FIXME. + +#include + +#include +#include + +#include + +void +java::lang::ConcreteProcess::destroy (void) +{ +} diff --git a/libjava/java/lang/natPosixProcess.cc b/libjava/java/lang/natPosixProcess.cc new file mode 100644 index 00000000000..30fa9d58229 --- /dev/null +++ b/libjava/java/lang/natPosixProcess.cc @@ -0,0 +1,203 @@ +// natPosixProcess.cc - Native side of POSIX process code. + +/* Copyright (C) 1998, 1999 Cygnus Solutions + + This file is part of libgcj. + +This software is copyrighted work licensed under the terms of the +Libgcj License. Please consult the file "LIBGCJ_LICENSE" for +details. */ + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern char **environ; + +void +java::lang::ConcreteProcess::destroy (void) +{ + if (! hasExited) + { + // Really kill it. + kill ((pid_t) pid, SIGKILL); + } +} + +jint +java::lang::ConcreteProcess::exitValue (void) +{ + if (! hasExited) + { + int wstat; + pid_t r = waitpid ((pid_t) pid, &wstat, WNOHANG); + if (r == -1) + { + jstring x = JvNewStringLatin1 (strerror (errno)); + _Jv_Throw (new IllegalThreadStateException (x)); + } + + hasExited = true; + // Just use the raw status. FIXME: what is right? + status = wstat; + } + + return status; +} + +jint +java::lang::ConcreteProcess::waitFor (void) +{ + if (! hasExited) + { + int wstat; + int r = waitpid ((pid_t) pid, &wstat, 0); + + if (r != -1) + { + hasExited = true; + // Just use the raw status. FIXME: what is right? + status = wstat; + } + + if (java::lang::Thread::interrupted()) + _Jv_Throw (new InterruptedException (JvNewStringLatin1 ("wait interrupted"))); + } + + return status; +} + +static char * +new_string (jstring string) +{ + jsize s = _Jv_GetStringUTFLength (string); + char *buf = (char *) _Jv_Malloc (s + 1); + _Jv_GetStringUTFRegion (string, 0, s, buf); + buf[s] = '\0'; + return buf; +} + +void +java::lang::ConcreteProcess::startProcess (jstringArray progarray, + jstringArray envp) +{ + using namespace java::io; + + hasExited = false; + + if (! progarray) + _Jv_Throw (new NullPointerException); + + // Transform arrays to native form. + // FIXME: we use malloc here. We shouldn't. If an exception is + // thrown we will leak memory. + char **args = (char **) _Jv_Malloc ((progarray->length + 1) + * sizeof (char *)); + + char **env = NULL; + if (envp) + env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *)); + +// for (int i = 0; i < progarray->length; ++i) +// args[i] = NULL; +// for (int i = 0; i < envp->length; ++i) +// env[i] = NULL; + + // FIXME: GC will fail here if _Jv_Malloc throws an exception. + // That's because we have to manually free the contents, but we + jstring *elts = elements (progarray); + for (int i = 0; i < progarray->length; ++i) + args[i] = new_string (elts[i]); + args[progarray->length] = NULL; + + if (envp) + { + elts = elements (envp); + for (int i = 0; i < envp->length; ++i) + args[i] = new_string (elts[i]); + args[envp->length] = NULL; + } + + // Create pipes for I/O. + int inp[2], outp[2], errp[2]; + + if (pipe (inp) + || pipe (outp) + || pipe (errp)) + { + ioerror: + // FIXME. + _Jv_Free (args); + if (env) + _Jv_Free (env); + _Jv_Throw (new IOException (JvNewStringLatin1 (strerror (errno)))); + } + + // We create the streams before forking. Otherwise if we had an + // error while creating the streams we would have run the child with + // no way to communicate with it. + errorStream = new FileInputStream (new FileDescriptor (errp[0])); + inputStream = new FileInputStream (new FileDescriptor (inp[0])); + outputStream = new FileOutputStream (new FileDescriptor (outp[1])); + + // We don't use vfork() because that would cause the local + // environment to be set by the child. + if ((pid = (jlong) fork ()) == -1) + goto ioerror; + + if (pid == 0) + { + // Child process, so remap descriptors and exec. + + if (envp) + environ = env; + + // We ignore errors from dup2 because they should never occur. + dup2 (outp[0], 0); + dup2 (inp[1], 1); + dup2 (errp[1], 2); + + close (inp[0]); + close (inp[1]); + close (errp[0]); + close (errp[1]); + close (outp[0]); + close (outp[1]); + + environ = env; + execvp (args[0], args); + _exit (127); + } + + // Parent. Close extra file descriptors and mark ours as + // close-on-exec. + close (outp[0]); + close (inp[1]); + close (errp[1]); + + fcntl (outp[1], F_SETFD, 1); + fcntl (inp[0], F_SETFD, 1); + fcntl (errp[0], F_SETFD, 1); +}