OSDN Git Service

* testsuite/libjava.jni/register2.java: New file.
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / natPosixProcess.cc
1 // natPosixProcess.cc - Native side of POSIX process code.
2
3 /* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 #include <config.h>
12
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <signal.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <pthread.h>
26
27 #include <gcj/cni.h>
28 #include <jvm.h>
29
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>
44
45 using gnu::java::nio::channels::FileChannelImpl;
46
47 extern char **environ;
48
49 static char *
50 new_string (jstring string)
51 {
52   jsize s = _Jv_GetStringUTFLength (string);
53   char *buf = (char *) _Jv_Malloc (s + 1);
54   _Jv_GetStringUTFRegion (string, 0, string->length(), buf);
55   buf[s] = '\0';
56   return buf;
57 }
58
59 static void
60 cleanup (char **args, char **env, char *path)
61 {
62   if (args != NULL)
63     {
64       for (int i = 0; args[i] != NULL; ++i)
65         _Jv_Free (args[i]);
66       _Jv_Free (args);
67     }
68   if (env != NULL)
69     {
70       for (int i = 0; env[i] != NULL; ++i)
71         _Jv_Free (env[i]);
72       _Jv_Free (env);
73     }
74   if (path != NULL)
75     _Jv_Free (path);
76 }
77
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
80 // a second time.
81 static void
82 myclose (int &fd)
83 {
84   if (fd != -1)
85     close (fd);
86   fd = -1;
87 }
88
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.
92 static void
93 sigchld_handler (int)
94 {
95   // Ignore.
96 }
97
98
99 // Get ready to enter the main reaper thread loop.
100 void
101 java::lang::ConcreteProcess$ProcessManager::init ()
102 {
103   using namespace java::lang;
104   // Remenber our PID so other threads can kill us.
105   reaperPID = (jlong) pthread_self ();
106
107   // SIGCHLD is blocked in all threads in posix-threads.cc.
108   // Setup the SIGCHLD handler.
109   struct sigaction sa;
110   memset (&sa, 0, sizeof (sa));
111
112   sa.sa_handler = sigchld_handler;
113   // We only want signals when the things exit.
114   sa.sa_flags = SA_NOCLDSTOP;
115
116   if (-1 == sigaction (SIGCHLD, &sa, NULL))
117     goto error;
118
119   // All OK.
120   return;
121
122 error:
123   throw new InternalError (JvNewStringUTF (strerror (errno)));
124 }
125
126 void
127 java::lang::ConcreteProcess$ProcessManager::waitForSignal ()
128 {
129   // Wait for SIGCHLD
130   sigset_t mask;
131   pthread_sigmask (0, NULL, &mask);
132   sigdelset (&mask, SIGCHLD);
133
134   // Use sigsuspend() instead of sigwait() as sigwait() doesn't play
135   // nicely with the GC's use of signals.
136   sigsuspend (&mask);
137
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.
143
144   // All OK.
145   return;
146 }
147
148 jboolean java::lang::ConcreteProcess$ProcessManager::reap ()
149 {
150   using namespace java::lang;
151
152   pid_t pid;
153
154   for (;;)
155     {
156       // Get the return code from a dead child process.
157       int status;
158       pid = waitpid ((pid_t) - 1, &status, WNOHANG);
159       if (pid == -1)
160         {
161           if (errno == ECHILD)
162             return false;
163           else
164             goto error;
165         }
166
167       if (pid == 0)
168         return true;   // No children to wait for.
169
170       // Look up the process in our pid map.
171       ConcreteProcess * process = removeProcessFromMap ((jlong) pid);
172
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.
175       if (process)
176         {
177           JvSynchronize sync (process);
178           process->status = WIFEXITED (status) ? WEXITSTATUS (status) : -1;
179           process->state = ConcreteProcess::STATE_TERMINATED;
180           process->processTerminationCleanup();
181           process->notifyAll ();
182         }
183     }
184
185 error:
186   throw new InternalError (JvNewStringUTF (strerror (errno)));
187 }
188
189 void
190 java::lang::ConcreteProcess$ProcessManager::signalReaper ()
191 {
192   int c = pthread_kill ((pthread_t) reaperPID, SIGCHLD);
193   if (c == 0)
194     return;
195   // pthread_kill() failed.
196   throw new InternalError (JvNewStringUTF (strerror (c)));
197 }
198
199 void
200 java::lang::ConcreteProcess::nativeDestroy ()
201 {
202   int c = kill ((pid_t) pid, SIGKILL);
203   if (c == 0)
204     return;
205   // kill() failed.
206   throw new InternalError (JvNewStringUTF (strerror (errno)));
207 }
208
209 void
210 java::lang::ConcreteProcess::nativeSpawn ()
211 {
212   using namespace java::io;
213
214   // Initialize all locals here to make cleanup simpler.
215   char **args = NULL;
216   char **env = NULL;
217   char *path = NULL;
218   int inp[2], outp[2], errp[2], msgp[2];
219   inp[0] = -1;
220   inp[1] = -1;
221   outp[0] = -1;
222   outp[1] = -1;
223   errp[0] = -1;
224   errp[1] = -1;
225   msgp[0] = -1;
226   msgp[1] = -1;
227   errorStream = NULL;
228   inputStream = NULL;
229   outputStream = NULL;
230
231   try
232     {
233       // Transform arrays to native form.
234     args = (char **) _Jv_Malloc ((progarray->length + 1) * sizeof (char *));
235
236       // Initialize so we can gracefully recover.
237       jstring *elts = elements (progarray);
238       for (int i = 0; i <= progarray->length; ++i)
239         args[i] = NULL;
240
241       for (int i = 0; i < progarray->length; ++i)
242         args[i] = new_string (elts[i]);
243       args[progarray->length] = NULL;
244
245       if (envp)
246         {
247           env = (char **) _Jv_Malloc ((envp->length + 1) * sizeof (char *));
248           elts = elements (envp);
249
250           // Initialize so we can gracefully recover.
251           for (int i = 0; i <= envp->length; ++i)
252             env[i] = NULL;
253
254           for (int i = 0; i < envp->length; ++i)
255             env[i] = new_string (elts[i]);
256           env[envp->length] = NULL;
257         }
258
259       // We allocate this here because we can't call malloc() after
260       // the fork.
261       if (dir != NULL)
262         path = new_string (dir->getPath ());
263
264       // Create pipes for I/O.  MSGP is for communicating exec()
265       // status.
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)));
269
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.
273     errorStream =
274       new FileInputStream (new
275                            FileChannelImpl (errp[0], FileChannelImpl::READ));
276     inputStream =
277       new FileInputStream (new
278                            FileChannelImpl (inp[0], FileChannelImpl::READ));
279     outputStream =
280       new FileOutputStream (new FileChannelImpl (outp[1],
281                                              FileChannelImpl::WRITE));
282
283       // We don't use vfork() because that would cause the local
284       // environment to be set by the child.
285
286     // Use temporary for fork result to avoid dirtying an extra page.
287     pid_t pid_tmp;
288     if ((pid_tmp = fork ()) == -1)
289       throw new IOException (JvNewStringUTF (strerror (errno)));
290
291     if (pid_tmp == 0)
292         {
293           // Child process, so remap descriptors, chdir and exec.
294           if (envp)
295             {
296               // Preserve PATH and LD_LIBRARY_PATH unless specified
297               // explicitly.
298               char *path_val = getenv ("PATH");
299               char *ld_path_val = getenv ("LD_LIBRARY_PATH");
300               environ = env;
301               if (path_val && getenv ("PATH") == NULL)
302                 {
303                 char *path_env =
304                   (char *) _Jv_Malloc (strlen (path_val) + 5 + 1);
305                   strcpy (path_env, "PATH=");
306                   strcat (path_env, path_val);
307                   putenv (path_env);
308                 }
309               if (ld_path_val && getenv ("LD_LIBRARY_PATH") == NULL)
310                 {
311                 char *ld_path_env =
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);
316                 }
317             }
318
319           // We ignore errors from dup2 because they should never occur.
320           dup2 (outp[0], 0);
321           dup2 (inp[1], 1);
322           dup2 (errp[1], 2);
323
324           // Use close and not myclose -- we're in the child, and we
325           // aren't worried about the possible race condition.
326           close (inp[0]);
327           close (inp[1]);
328           close (errp[0]);
329           close (errp[1]);
330           close (outp[0]);
331           close (outp[1]);
332           close (msgp[0]);
333           
334           // Change directory.
335           if (path != NULL)
336             {
337               if (chdir (path) != 0)
338                 {
339                   char c = errno;
340                   write (msgp[1], &c, 1);
341                   _exit (127);
342                 }
343             }
344
345           // Make sure that SIGCHLD is unblocked for the new process.
346           sigset_t mask;
347           sigemptyset (&mask);
348           sigaddset (&mask, SIGCHLD);
349           sigprocmask (SIG_UNBLOCK, &mask, NULL);
350
351           execvp (args[0], args);
352
353           // Send the parent notification that the exec failed.
354           char c = errno;
355           write (msgp[1], &c, 1);
356           _exit (127);
357         }
358
359       // Parent.  Close extra file descriptors and mark ours as
360       // close-on-exec.
361       pid = (jlong) pid_tmp;
362
363       myclose (outp[0]);
364       myclose (inp[1]);
365       myclose (errp[1]);
366       myclose (msgp[1]);
367
368       char c;
369       int r = read (msgp[0], &c, 1);
370       if (r == -1)
371       throw new IOException (JvNewStringUTF (strerror (errno)));
372       else if (r != 0)
373       throw new IOException (JvNewStringUTF (strerror (c)));
374     }
375   catch (java::lang::Throwable *thrown)
376     {
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.
382
383       try
384         {
385           if (inputStream != NULL)
386             inputStream->close ();
387           else
388             myclose (inp[0]);
389         }
390       catch (java::lang::Throwable *ignore)
391         {
392         }
393
394       try
395         {
396           if (outputStream != NULL)
397             outputStream->close ();
398           else
399             myclose (outp[1]);
400         }
401       catch (java::lang::Throwable *ignore)
402         {
403         }
404
405       try
406         {
407           if (errorStream != NULL)
408             errorStream->close ();
409           else
410             myclose (errp[0]);
411         }
412       catch (java::lang::Throwable *ignore)
413         {
414         }
415
416       // These are potentially duplicate, but it doesn't matter due to
417       // the use of myclose.
418       myclose (outp[0]);
419       myclose (inp[1]);
420       myclose (errp[1]);
421       myclose (msgp[1]);
422
423     exception = thrown;
424     }
425
426   myclose (msgp[0]);
427   cleanup (args, env, path);
428
429   if (exception == NULL)
430     {
431       fcntl (outp[1], F_SETFD, FD_CLOEXEC);
432       fcntl (inp[0], F_SETFD, FD_CLOEXEC);
433       fcntl (errp[0], F_SETFD, FD_CLOEXEC);
434     }
435 }