1 // natPosixProcess.cc - Native side of POSIX process code.
3 /* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
18 #include <sys/types.h>
30 #include <java/lang/ConcreteProcess$ProcessManager.h>
31 #include <java/lang/ConcreteProcess.h>
32 #include <java/lang/IllegalThreadStateException.h>
33 #include <java/lang/InternalError.h>
34 #include <java/lang/InterruptedException.h>
35 #include <java/lang/NullPointerException.h>
36 #include <java/lang/Thread.h>
37 #include <java/io/File.h>
38 #include <java/io/FileDescriptor.h>
39 #include <gnu/java/nio/channels/FileChannelImpl.h>
40 #include <java/io/FileInputStream.h>
41 #include <java/io/FileOutputStream.h>
42 #include <java/io/IOException.h>
43 #include <java/lang/OutOfMemoryError.h>
45 using gnu::java::nio::channels::FileChannelImpl;
47 extern char **environ;
50 new_string (jstring string)
52 jsize s = _Jv_GetStringUTFLength (string);
53 char *buf = (char *) _Jv_Malloc (s + 1);
54 _Jv_GetStringUTFRegion (string, 0, string->length(), buf);
60 cleanup (char **args, char **env, char *path)
64 for (int i = 0; args[i] != NULL; ++i)
70 for (int i = 0; env[i] != NULL; ++i)
78 // This makes our error handling a bit simpler and it lets us avoid
79 // thread bugs where we close a possibly-reopened file descriptor for
89 // There has to be a signal handler in order to be able to
90 // sigwait() on SIGCHLD. The information passed is ignored as it
91 // will be recovered by the waitpid() call.
99 // Get ready to enter the main reaper thread loop.
101 java::lang::ConcreteProcess$ProcessManager::init ()
103 using namespace java::lang;
104 // Remenber our PID so other threads can kill us.
105 reaperPID = (jlong) pthread_self ();
107 // SIGCHLD is blocked in all threads in posix-threads.cc.
108 // Setup the SIGCHLD handler.
110 memset (&sa, 0, sizeof (sa));
112 sa.sa_handler = sigchld_handler;
113 // We only want signals when the things exit.
114 sa.sa_flags = SA_NOCLDSTOP;
116 if (-1 == sigaction (SIGCHLD, &sa, NULL))
123 throw new InternalError (JvNewStringUTF (strerror (errno)));
127 java::lang::ConcreteProcess$ProcessManager::waitForSignal ()
131 pthread_sigmask (0, NULL, &mask);
132 sigdelset (&mask, SIGCHLD);
134 // Use sigsuspend() instead of sigwait() as sigwait() doesn't play
135 // nicely with the GC's use of signals.
138 // Do not check sigsuspend return value. The only legitimate return
139 // is EINTR, but there is a known kernel bug affecting alpha-linux
140 // wrt sigsuspend+handler+sigreturn that can result in a return value
141 // of __NR_sigsuspend and errno unset. Don't fail unnecessarily on
142 // older kernel versions.
148 jboolean java::lang::ConcreteProcess$ProcessManager::reap ()
150 using namespace java::lang;
156 // Get the return code from a dead child process.
158 pid = waitpid ((pid_t) - 1, &status, WNOHANG);
168 return true; // No children to wait for.
170 // Look up the process in our pid map.
171 ConcreteProcess * process = removeProcessFromMap ((jlong) pid);
173 // Note that if process==NULL, then we have an unknown child.
174 // This is not common, but can happen, and isn't an error.
177 JvSynchronize sync (process);
178 process->status = WIFEXITED (status) ? WEXITSTATUS (status) : -1;
179 process->state = ConcreteProcess::STATE_TERMINATED;
180 process->processTerminationCleanup();
181 process->notifyAll ();
186 throw new InternalError (JvNewStringUTF (strerror (errno)));
190 java::lang::ConcreteProcess$ProcessManager::signalReaper ()
192 int c = pthread_kill ((pthread_t) reaperPID, SIGCHLD);
195 // pthread_kill() failed.
196 throw new InternalError (JvNewStringUTF (strerror (c)));
200 java::lang::ConcreteProcess::nativeDestroy ()
202 int c = kill ((pid_t) pid, SIGKILL);
206 throw new InternalError (JvNewStringUTF (strerror (errno)));
210 java::lang::ConcreteProcess::nativeSpawn ()
212 using namespace java::io;
214 // Initialize all locals here to make cleanup simpler.
218 int inp[2], outp[2], errp[2], msgp[2];
233 // Transform arrays to native form.
234 args = (char **) _Jv_Malloc ((progarray->length + 1) * sizeof (char *));
236 // Initialize so we can gracefully recover.
237 jstring *elts = elements (progarray);
238 for (int i = 0; i <= progarray->length; ++i)
241 for (int i = 0; i < progarray->length; ++i)
242 args[i] = new_string (elts[i]);
243 args[progarray->length] = NULL;
247 env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *));
248 elts = elements (envp);
250 // Initialize so we can gracefully recover.
251 for (int i = 0; i <= envp->length; ++i)
254 for (int i = 0; i < envp->length; ++i)
255 env[i] = new_string (elts[i]);
256 env[envp->length] = NULL;
259 // We allocate this here because we can't call malloc() after
262 path = new_string (dir->getPath ());
264 // Create pipes for I/O. MSGP is for communicating exec()
266 if (pipe (inp) || pipe (outp) || pipe (errp) || pipe (msgp)
267 || fcntl (msgp[1], F_SETFD, FD_CLOEXEC))
268 throw new IOException (JvNewStringUTF (strerror (errno)));
270 // We create the streams before forking. Otherwise if we had an
271 // error while creating the streams we would have run the child
272 // with no way to communicate with it.
274 new FileInputStream (new
275 FileChannelImpl (errp[0], FileChannelImpl::READ));
277 new FileInputStream (new
278 FileChannelImpl (inp[0], FileChannelImpl::READ));
280 new FileOutputStream (new FileChannelImpl (outp[1],
281 FileChannelImpl::WRITE));
283 // We don't use vfork() because that would cause the local
284 // environment to be set by the child.
286 // Use temporary for fork result to avoid dirtying an extra page.
288 if ((pid_tmp = fork ()) == -1)
289 throw new IOException (JvNewStringUTF (strerror (errno)));
293 // Child process, so remap descriptors, chdir and exec.
296 // Preserve PATH and LD_LIBRARY_PATH unless specified
298 char *path_val = getenv ("PATH");
299 char *ld_path_val = getenv ("LD_LIBRARY_PATH");
301 if (path_val && getenv ("PATH") == NULL)
304 (char *) _Jv_Malloc (strlen (path_val) + 5 + 1);
305 strcpy (path_env, "PATH=");
306 strcat (path_env, path_val);
309 if (ld_path_val && getenv ("LD_LIBRARY_PATH") == NULL)
312 (char *) _Jv_Malloc (strlen (ld_path_val) + 16 + 1);
313 strcpy (ld_path_env, "LD_LIBRARY_PATH=");
314 strcat (ld_path_env, ld_path_val);
315 putenv (ld_path_env);
319 // We ignore errors from dup2 because they should never occur.
324 // Use close and not myclose -- we're in the child, and we
325 // aren't worried about the possible race condition.
337 if (chdir (path) != 0)
340 write (msgp[1], &c, 1);
345 // Make sure that SIGCHLD is unblocked for the new process.
348 sigaddset (&mask, SIGCHLD);
349 sigprocmask (SIG_UNBLOCK, &mask, NULL);
351 execvp (args[0], args);
353 // Send the parent notification that the exec failed.
355 write (msgp[1], &c, 1);
359 // Parent. Close extra file descriptors and mark ours as
361 pid = (jlong) pid_tmp;
369 int r = read (msgp[0], &c, 1);
371 throw new IOException (JvNewStringUTF (strerror (errno)));
373 throw new IOException (JvNewStringUTF (strerror (c)));
375 catch (java::lang::Throwable *thrown)
377 // Do some cleanup we only do on failure. If a stream object
378 // has been created, we must close the stream itself (to avoid
379 // duplicate closes when the stream object is collected).
380 // Otherwise we simply close the underlying file descriptor.
381 // We ignore errors here as they are uninteresting.
385 if (inputStream != NULL)
386 inputStream->close ();
390 catch (java::lang::Throwable *ignore)
396 if (outputStream != NULL)
397 outputStream->close ();
401 catch (java::lang::Throwable *ignore)
407 if (errorStream != NULL)
408 errorStream->close ();
412 catch (java::lang::Throwable *ignore)
416 // These are potentially duplicate, but it doesn't matter due to
417 // the use of myclose.
427 cleanup (args, env, path);
429 if (exception == NULL)
431 fcntl (outp[1], F_SETFD, FD_CLOEXEC);
432 fcntl (inp[0], F_SETFD, FD_CLOEXEC);
433 fcntl (errp[0], F_SETFD, FD_CLOEXEC);