OSDN Git Service

2003-05-19 Michael Koch <konqueror@gmx.de>
[pf3gnuchains/gcc-fork.git] / libjava / posix.cc
1 // posix.cc -- Helper functions for POSIX-flavored OSs.
2
3 /* Copyright (C) 2000, 2001, 2002  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 #include "posix.h"
14
15 #include <stdlib.h>
16 #include <errno.h>
17 #include <signal.h>
18
19 #include <jvm.h>
20 #include <java/lang/Thread.h>
21 #include <java/io/InterruptedIOException.h>
22 #include <java/util/Properties.h>
23
24 #if defined (ECOS)
25 extern "C" unsigned long long _clock (void);
26 #endif
27
28 #if defined(HAVE_PROC_SELF_EXE)
29 static char exec_name[20];
30   // initialized in _Jv_platform_initialize()
31 #endif
32
33 const char *_Jv_ThisExecutable (void)
34 {
35 #if defined(DISABLE_MAIN_ARGS)
36   return "[Embedded App]";
37 #elif defined(HAVE_PROC_SELF_EXE)
38   return exec_name;
39     // initialized in _Jv_platform_initialize()
40 #else
41   return _Jv_GetSafeArg (0);
42 #endif
43 }
44
45 // gettimeofday implementation.
46 jlong
47 _Jv_platform_gettimeofday ()
48 {
49 #if defined (HAVE_GETTIMEOFDAY)
50   timeval tv;
51   gettimeofday (&tv, NULL);
52   return (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL);
53 #elif defined (HAVE_TIME)
54   return time (NULL) * 1000LL;
55 #elif defined (HAVE_FTIME)
56   struct timeb t;
57   ftime (&t);
58   return (t.time * 1000LL) + t.millitm;
59 #elif defined (ECOS)
60   // FIXME.
61   return _clock();
62 #else
63   // In the absence of any function, time remains forever fixed.
64   return 23000;
65 #endif
66 }
67
68 // Platform-specific VM initialization.
69 void
70 _Jv_platform_initialize (void)
71 {
72 #if defined (HAVE_SIGACTION)
73   // We only want this on POSIX systems.
74   struct sigaction act;
75   act.sa_handler = SIG_IGN;
76   sigemptyset (&act.sa_mask);
77   act.sa_flags = 0;
78   sigaction (SIGPIPE, &act, NULL);
79 #else
80   signal (SIGPIPE, SIG_IGN);
81 #endif
82
83 #if defined (HAVE_PROC_SELF_EXE)
84   // Compute our executable name
85   sprintf (exec_name, "/proc/%d/exe", getpid ());
86 #endif
87 }
88
89 // Set platform-specific System properties.
90 void
91 _Jv_platform_initProperties (java::util::Properties* newprops)
92 {
93   // A convenience define.
94 #define SET(Prop,Val) \
95   newprops->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
96
97   SET ("file.separator", "/");
98   SET ("path.separator", ":");
99   SET ("line.separator", "\n");
100   char *tmpdir = ::getenv("TMPDIR");
101   if (! tmpdir)
102     tmpdir = "/tmp";
103   SET ("java.io.tmpdir", tmpdir);
104 }
105
106 static inline void
107 internal_gettimeofday (struct timeval *result)
108 {
109 #if defined (HAVE_GETTIMEOFDAY)
110   gettimeofday (result, NULL);
111 #else
112   jlong val = _Jv_platform_gettimeofday ();
113   result->tv_sec = val / 1000;
114   result->tv_usec = (val % 1000) * 1000;
115 #endif /* HAVE_GETTIMEOFDAY */
116 }
117
118 // A wrapper for select() which ignores EINTR.
119 int
120 _Jv_select (int n, fd_set *readfds, fd_set  *writefds,
121             fd_set *exceptfds, struct timeval *timeout)
122 {
123 #ifdef HAVE_SELECT
124   // If we have a timeout, compute the absolute ending time.
125   struct timeval end, delay;
126   if (timeout)
127     {
128       internal_gettimeofday (&end);
129       end.tv_usec += timeout->tv_usec;
130       if (end.tv_usec >= 1000000)
131         {
132           ++end.tv_sec;
133           end.tv_usec -= 1000000;
134         }
135       end.tv_sec += timeout->tv_sec;
136       delay = *timeout;
137     }
138   else
139     {
140       // Placate compiler.
141       delay.tv_sec = delay.tv_usec = 0;
142     }
143
144   while (1)
145     {
146       int r = select (n, readfds, writefds, exceptfds,
147                       timeout ? &delay : NULL);
148       if (r != -1 || errno != EINTR)
149         return r;
150
151       // Here we know we got EINTR.
152       if (java::lang::Thread::interrupted ())
153         throw new java::io::InterruptedIOException (JvNewStringLatin1 ("select interrupted"));
154
155       struct timeval after;
156       if (timeout)
157         {
158           internal_gettimeofday (&after);
159           // Now compute new timeout argument.
160           delay.tv_usec = end.tv_usec - after.tv_usec;
161           delay.tv_sec = end.tv_sec - after.tv_sec;
162           if (delay.tv_usec < 0)
163             {
164               --delay.tv_sec;
165               delay.tv_usec += 1000000;
166             }
167           if (delay.tv_sec < 0)
168             {
169               // We assume that the user wants a valid select() call
170               // more than precise timing.  So if we get a series of
171               // EINTR we just keep trying with delay 0 until we get a
172               // valid result.
173               delay.tv_sec = 0;
174             }
175         }
176     }
177 #else /* HAVE_SELECT */
178   return 0;
179 #endif
180 }