posix.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. // posix.cc -- Helper functions for POSIX-flavored OSs.
  2. /* Copyright (C) 2000, 2001, 2002, 2006 Free Software Foundation
  3. This file is part of libgcj.
  4. This software is copyrighted work licensed under the terms of the
  5. Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
  6. details. */
  7. #include <config.h>
  8. #include "posix.h"
  9. #include <stdlib.h>
  10. #include <errno.h>
  11. #include <signal.h>
  12. #include <stdio.h>
  13. #ifdef HAVE_DLFCN_H
  14. #include <dlfcn.h>
  15. #endif
  16. #include <jvm.h>
  17. #include <java-stack.h>
  18. #include <java/lang/Thread.h>
  19. #include <java/io/InterruptedIOException.h>
  20. #include <java/util/Properties.h>
  21. #if defined (ECOS)
  22. extern "C" unsigned long long _clock (void);
  23. #endif
  24. #if defined(HAVE_PROC_SELF_EXE)
  25. static char exec_name[20];
  26. // initialized in _Jv_platform_initialize()
  27. #endif
  28. const char *_Jv_ThisExecutable (void)
  29. {
  30. #if defined(DISABLE_MAIN_ARGS)
  31. return "[Embedded App]";
  32. #elif defined(HAVE_PROC_SELF_EXE)
  33. return exec_name;
  34. // initialized in _Jv_platform_initialize()
  35. #else
  36. return _Jv_GetSafeArg (0);
  37. #endif
  38. }
  39. // gettimeofday implementation.
  40. jlong
  41. _Jv_platform_gettimeofday ()
  42. {
  43. #if defined (HAVE_GETTIMEOFDAY)
  44. timeval tv;
  45. gettimeofday (&tv, NULL);
  46. return (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL);
  47. #elif defined (HAVE_TIME)
  48. return time (NULL) * 1000LL;
  49. #elif defined (HAVE_FTIME)
  50. struct timeb t;
  51. ftime (&t);
  52. return (t.time * 1000LL) + t.millitm;
  53. #elif defined (ECOS)
  54. // FIXME.
  55. return _clock();
  56. #else
  57. // In the absence of any function, time remains forever fixed.
  58. return 23000;
  59. #endif
  60. }
  61. jlong
  62. _Jv_platform_nanotime ()
  63. {
  64. #ifdef HAVE_CLOCK_GETTIME
  65. struct timespec now;
  66. clockid_t id;
  67. #ifdef CLOCK_MONOTONIC
  68. id = CLOCK_MONOTONIC;
  69. #elif defined (CLOCK_HIGHRES)
  70. id = CLOCK_HIGHRES;
  71. #else
  72. id = CLOCK_REALTIME;
  73. #endif
  74. if (clock_gettime (id, &now) == 0)
  75. {
  76. jlong result = (jlong) now.tv_sec;
  77. result = result * 1000000000LL + now.tv_nsec;
  78. return result;
  79. }
  80. // clock_gettime failed, but we can fall through.
  81. #endif // HAVE_CLOCK_GETTIME
  82. #if defined (HAVE_GETTIMEOFDAY)
  83. {
  84. timeval tv;
  85. gettimeofday (&tv, NULL);
  86. return (tv.tv_sec * 1000000000LL) + tv.tv_usec * 1000LL;
  87. }
  88. #else
  89. return _Jv_platform_gettimeofday () * 1000000LL;
  90. #endif
  91. }
  92. // Platform-specific VM initialization.
  93. void
  94. _Jv_platform_initialize (void)
  95. {
  96. #if defined (HAVE_SIGACTION)
  97. // We only want this on POSIX systems.
  98. struct sigaction act;
  99. act.sa_handler = SIG_IGN;
  100. sigemptyset (&act.sa_mask);
  101. act.sa_flags = 0;
  102. sigaction (SIGPIPE, &act, NULL);
  103. #else
  104. signal (SIGPIPE, SIG_IGN);
  105. #endif
  106. #if defined (HAVE_PROC_SELF_EXE)
  107. // Compute our executable name
  108. sprintf (exec_name, "/proc/%d/exe", getpid ());
  109. #endif
  110. }
  111. // Set platform-specific System properties.
  112. void
  113. _Jv_platform_initProperties (java::util::Properties* newprops)
  114. {
  115. // A convenience define.
  116. #define SET(Prop,Val) \
  117. newprops->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
  118. SET ("file.separator", "/");
  119. SET ("path.separator", ":");
  120. SET ("line.separator", "\n");
  121. const char *tmpdir = ::getenv("TMPDIR");
  122. if (! tmpdir)
  123. tmpdir = "/tmp";
  124. SET ("java.io.tmpdir", tmpdir);
  125. const char *zoneinfodir = ::getenv("TZDATA");
  126. if (! zoneinfodir)
  127. zoneinfodir = "/usr/share/zoneinfo";
  128. SET ("gnu.java.util.zoneinfo.dir", zoneinfodir);
  129. }
  130. static inline void
  131. internal_gettimeofday (struct timeval *result)
  132. {
  133. #if defined (HAVE_GETTIMEOFDAY)
  134. gettimeofday (result, NULL);
  135. #else
  136. jlong val = _Jv_platform_gettimeofday ();
  137. result->tv_sec = val / 1000;
  138. result->tv_usec = (val % 1000) * 1000;
  139. #endif /* HAVE_GETTIMEOFDAY */
  140. }
  141. // A wrapper for select() which ignores EINTR.
  142. int
  143. _Jv_select (int n, fd_set *readfds, fd_set *writefds,
  144. fd_set *exceptfds, struct timeval *timeout)
  145. {
  146. #ifdef HAVE_SELECT
  147. // If we have a timeout, compute the absolute ending time.
  148. struct timeval end, delay;
  149. if (timeout)
  150. {
  151. internal_gettimeofday (&end);
  152. end.tv_usec += timeout->tv_usec;
  153. if (end.tv_usec >= 1000000)
  154. {
  155. ++end.tv_sec;
  156. end.tv_usec -= 1000000;
  157. }
  158. end.tv_sec += timeout->tv_sec;
  159. delay = *timeout;
  160. }
  161. else
  162. {
  163. // Placate compiler.
  164. delay.tv_sec = delay.tv_usec = 0;
  165. }
  166. while (1)
  167. {
  168. int r = select (n, readfds, writefds, exceptfds,
  169. timeout ? &delay : NULL);
  170. if (r != -1 || errno != EINTR)
  171. return r;
  172. // Here we know we got EINTR.
  173. if (java::lang::Thread::interrupted ())
  174. throw new java::io::InterruptedIOException (JvNewStringLatin1 ("select interrupted"));
  175. struct timeval after;
  176. if (timeout)
  177. {
  178. internal_gettimeofday (&after);
  179. // Now compute new timeout argument.
  180. delay.tv_usec = end.tv_usec - after.tv_usec;
  181. delay.tv_sec = end.tv_sec - after.tv_sec;
  182. if (delay.tv_usec < 0)
  183. {
  184. --delay.tv_sec;
  185. delay.tv_usec += 1000000;
  186. }
  187. if (delay.tv_sec < 0)
  188. {
  189. // We assume that the user wants a valid select() call
  190. // more than precise timing. So if we get a series of
  191. // EINTR we just keep trying with delay 0 until we get a
  192. // valid result.
  193. delay.tv_sec = 0;
  194. }
  195. }
  196. }
  197. #else /* HAVE_SELECT */
  198. return 0;
  199. #endif
  200. }
  201. // Given an address, find the object that defines it and the nearest
  202. // defined symbol to that address. Returns 0 if no object defines this
  203. // address.
  204. int
  205. _Jv_platform_dladdr (void *addr, _Jv_AddrInfo *info)
  206. {
  207. int ret_val = 0;
  208. #if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
  209. Dl_info addr_info;
  210. ret_val = dladdr (addr, &addr_info);
  211. if (ret_val != 0)
  212. {
  213. info->file_name = addr_info.dli_fname;
  214. info->base = addr_info.dli_fbase;
  215. info->sym_name = addr_info.dli_sname;
  216. info->sym_addr = addr_info.dli_saddr;
  217. }
  218. #else
  219. info->file_name = NULL;
  220. info->base = NULL;
  221. info->sym_name = NULL;
  222. info->sym_addr = NULL;
  223. #endif
  224. return ret_val;
  225. }