posix.cc 4.1 KB

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