1 // natPosixProcess.cc - Native side of POSIX process code.
3 /* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation
6 This file is part of libgcj.
8 This software is copyrighted work licensed under the terms of the
9 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
19 #include <sys/types.h>
21 #ifdef HAVE_SYS_RESOURCE_H
22 #include <sys/resource.h>
32 #include <posix-threads.h>
35 #include <java/lang/PosixProcess$ProcessManager.h>
36 #include <java/lang/PosixProcess.h>
37 #include <java/lang/IllegalThreadStateException.h>
38 #include <java/lang/InternalError.h>
39 #include <java/lang/InterruptedException.h>
40 #include <java/lang/NullPointerException.h>
41 #include <java/lang/Thread.h>
42 #include <java/io/File.h>
43 #include <java/io/FileDescriptor.h>
44 #include <gnu/java/nio/channels/FileChannelImpl.h>
45 #include <java/io/FileInputStream.h>
46 #include <java/io/FileOutputStream.h>
47 #include <java/io/IOException.h>
48 #include <java/lang/OutOfMemoryError.h>
49 #include <java/lang/PosixProcess$EOFInputStream.h>
51 using gnu::java::nio::channels::FileChannelImpl;
52 using namespace java::lang;
54 extern char **environ;
57 new_string (jstring string)
59 jsize s = _Jv_GetStringUTFLength (string);
60 char *buf = (char *) _Jv_Malloc (s + 1);
61 _Jv_GetStringUTFRegion (string, 0, string->length(), buf);
67 cleanup (char **args, char **env, char *path)
71 for (int i = 0; args[i] != NULL; ++i)
77 for (int i = 0; env[i] != NULL; ++i)
85 // This makes our error handling a bit simpler and it lets us avoid
86 // thread bugs where we close a possibly-reopened file descriptor for
98 struct ProcessManagerInternal
101 struct sigaction old_sigaction;
106 // There has to be a signal handler in order to be able to
107 // sigwait() on SIGCHLD. The information passed is ignored as it
108 // will be recovered by the waitpid() call.
110 sigchld_handler (int sig, siginfo_t *si, void *third)
112 if (PosixProcess$ProcessManager::nativeData != NULL)
114 ProcessManagerInternal *pmi =
115 (ProcessManagerInternal *)PosixProcess$ProcessManager::nativeData;
117 ::write(pmi->pipe_ends[1], &c, 1);
118 if (pmi->old_sigaction.sa_handler != SIG_DFL
119 && pmi->old_sigaction.sa_handler != SIG_IGN)
121 if ((pmi->old_sigaction.sa_flags & SA_SIGINFO) != 0)
122 pmi->old_sigaction.sa_sigaction(sig, si, third);
124 (*pmi->old_sigaction.sa_handler)(sig);
130 // Get ready to enter the main reaper thread loop.
132 java::lang::PosixProcess$ProcessManager::init ()
134 // The nativeData is static to avoid races installing the signal
135 // handler in the case that it is chained.
136 if (nativeData == NULL )
138 ProcessManagerInternal *pmi =
139 (ProcessManagerInternal *)JvAllocBytes(sizeof(ProcessManagerInternal));
141 if (0 != ::pipe(pmi->pipe_ends))
144 // Make writing non-blocking so that the signal handler will
146 int fl = ::fcntl(pmi->pipe_ends[1], F_GETFL);
147 ::fcntl(pmi->pipe_ends[1], F_SETFL, fl | O_NONBLOCK);
149 nativeData = (::gnu::gcj::RawDataManaged *)pmi;
151 // SIGCHLD is blocked in all threads in posix-threads.cc.
152 // Setup the SIGCHLD handler.
154 memset (&sa, 0, sizeof (sa));
156 sa.sa_sigaction = sigchld_handler;
157 // We only want signals when the things exit.
158 sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
160 if (-1 == sigaction (SIGCHLD, &sa, &pmi->old_sigaction))
167 throw new InternalError (JvNewStringUTF (strerror (errno)));
171 java::lang::PosixProcess$ProcessManager::waitForSignal ()
174 _Jv_UnBlockSigchld();
175 ProcessManagerInternal *pmi = (ProcessManagerInternal *)nativeData;
177 // Try to read multiple (64) notifications in one go.
179 ::read(pmi->pipe_ends[0], c, sizeof (c));
186 jboolean java::lang::PosixProcess$ProcessManager::reap (PosixProcess *p)
190 // Try to get the return code from the child process.
192 rv = ::waitpid ((pid_t)p->pid, &status, WNOHANG);
194 throw new InternalError (JvNewStringUTF (strerror (errno)));
197 return false; // No children to wait for.
199 JvSynchronize sync (p);
200 p->status = WIFEXITED (status) ? WEXITSTATUS (status) : -1;
201 p->state = PosixProcess::STATE_TERMINATED;
202 p->processTerminationCleanup();
208 java::lang::PosixProcess$ProcessManager::signalReaper ()
210 ProcessManagerInternal *pmi = (ProcessManagerInternal *)nativeData;
212 ::write(pmi->pipe_ends[1], &c, 1);
213 // Ignore errors. If EPIPE the reaper has already exited.
217 java::lang::PosixProcess::nativeDestroy ()
219 int c = ::kill ((pid_t) pid, SIGKILL);
223 throw new InternalError (JvNewStringUTF (strerror (errno)));
227 java::lang::PosixProcess::nativeSpawn ()
229 using namespace java::io;
231 // Initialize all locals here to make cleanup simpler.
235 int inp[2], outp[2], errp[2], msgp[2];
250 // Transform arrays to native form.
251 args = (char **) _Jv_Malloc ((progarray->length + 1) * sizeof (char *));
253 // Initialize so we can gracefully recover.
254 jstring *elts = elements (progarray);
255 for (int i = 0; i <= progarray->length; ++i)
258 for (int i = 0; i < progarray->length; ++i)
259 args[i] = new_string (elts[i]);
260 args[progarray->length] = NULL;
264 bool need_path = true;
265 bool need_ld_library_path = true;
268 // Preserve PATH and LD_LIBRARY_PATH unless specified
269 // explicitly. We need three extra slots. Potentially PATH
270 // and LD_LIBRARY_PATH will be added plus the NULL
272 env = (char **) _Jv_Malloc ((envp->length + 3) * sizeof (char *));
273 elts = elements (envp);
275 // Initialize so we can gracefully recover.
276 for (i = 0; i < envp->length + 3; ++i)
279 for (i = 0; i < envp->length; ++i)
281 env[i] = new_string (elts[i]);
282 if (!strncmp (env[i], "PATH=", sizeof("PATH=")))
284 if (!strncmp (env[i], "LD_LIBRARY_PATH=",
285 sizeof("LD_LIBRARY_PATH=")))
286 need_ld_library_path = false;
291 char *path_val = getenv ("PATH");
294 env[i] = (char *) _Jv_Malloc (strlen (path_val) +
295 sizeof("PATH=") + 1);
296 strcpy (env[i], "PATH=");
297 strcat (env[i], path_val);
301 if (need_ld_library_path)
303 char *path_val = getenv ("LD_LIBRARY_PATH");
307 (char *) _Jv_Malloc (strlen (path_val) +
308 sizeof("LD_LIBRARY_PATH=") + 1);
309 strcpy (env[i], "LD_LIBRARY_PATH=");
310 strcat (env[i], path_val);
317 // We allocate this here because we can't call malloc() after
320 path = new_string (dir->getPath ());
322 // Create pipes for I/O. MSGP is for communicating exec()
323 // status. If redirecting stderr to stdout, we don't need to
324 // create the ERRP pipe.
325 if (pipe (inp) || pipe (outp) || pipe (msgp)
326 || fcntl (msgp[1], F_SETFD, FD_CLOEXEC))
327 throw new IOException (JvNewStringUTF (strerror (errno)));
328 if (! redirect && pipe (errp))
329 throw new IOException (JvNewStringUTF (strerror (errno)));
331 // We create the streams before forking. Otherwise if we had an
332 // error while creating the streams we would have run the child
333 // with no way to communicate with it.
335 errorStream = PosixProcess$EOFInputStream::instance;
338 new FileInputStream (new
339 FileChannelImpl (errp[0],
340 FileChannelImpl::READ));
342 new FileInputStream (new
343 FileChannelImpl (inp[0], FileChannelImpl::READ));
345 new FileOutputStream (new FileChannelImpl (outp[1],
346 FileChannelImpl::WRITE));
348 // We don't use vfork() because that would cause the local
349 // environment to be set by the child.
351 // Use temporary for fork result to avoid dirtying an extra page.
353 if ((pid_tmp = fork ()) == -1)
354 throw new IOException (JvNewStringUTF (strerror (errno)));
358 // Child process, so remap descriptors, chdir and exec.
362 // We ignore errors from dup2 because they should never occur.
365 dup2 (redirect ? inp[1] : errp[1], 2);
367 // Use close and not myclose -- we're in the child, and we
368 // aren't worried about the possible race condition.
383 if (chdir (path) != 0)
386 write (msgp[1], &c, 1);
390 // Make sure all file descriptors are closed. In
391 // multi-threaded programs, there is a race between when a
392 // descriptor is obtained, when we can set FD_CLOEXEC, and
393 // fork(). If the fork occurs before FD_CLOEXEC is set, the
394 // descriptor would leak to the execed process if we did not
395 // manually close it. So that is what we do. Since we
396 // close all the descriptors, it is redundant to set
397 // FD_CLOEXEC on them elsewhere.
399 #ifdef HAVE_GETRLIMIT
401 int rv = getrlimit(RLIMIT_NOFILE, &rl);
403 max_fd = rl.rlim_max - 1;
411 if (max_fd != msgp[1])
415 // Make sure that SIGCHLD is unblocked for the new process.
418 sigaddset (&mask, SIGCHLD);
419 sigprocmask (SIG_UNBLOCK, &mask, NULL);
421 execvp (args[0], args);
423 // Send the parent notification that the exec failed.
425 write (msgp[1], &c, 1);
429 // Parent. Close extra file descriptors and mark ours as
431 pid = (jlong) pid_tmp;
440 int r = read (msgp[0], &c, 1);
442 throw new IOException (JvNewStringUTF (strerror (errno)));
444 throw new IOException (JvNewStringUTF (strerror (c)));
446 catch (java::lang::Throwable *thrown)
448 // Do some cleanup we only do on failure. If a stream object
449 // has been created, we must close the stream itself (to avoid
450 // duplicate closes when the stream object is collected).
451 // Otherwise we simply close the underlying file descriptor.
452 // We ignore errors here as they are uninteresting.
456 if (inputStream != NULL)
457 inputStream->close ();
461 catch (java::lang::Throwable *ignore)
467 if (outputStream != NULL)
468 outputStream->close ();
472 catch (java::lang::Throwable *ignore)
478 if (errorStream != NULL)
479 errorStream->close ();
483 catch (java::lang::Throwable *ignore)
487 // These are potentially duplicate, but it doesn't matter due to
488 // the use of myclose.
499 cleanup (args, env, path);