mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			251 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			251 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| // posix.cc -- Helper functions for POSIX-flavored OSs.
 | |
| 
 | |
| /* Copyright (C) 2000, 2001, 2002, 2006  Free Software Foundation
 | |
| 
 | |
|    This file is part of libgcj.
 | |
| 
 | |
| This software is copyrighted work licensed under the terms of the
 | |
| Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 | |
| details.  */
 | |
| 
 | |
| #include <config.h>
 | |
| 
 | |
| #include "posix.h"
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include <errno.h>
 | |
| #include <signal.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| #ifdef HAVE_DLFCN_H
 | |
| #include <dlfcn.h>
 | |
| #endif
 | |
| 
 | |
| #include <jvm.h>
 | |
| #include <java-stack.h>
 | |
| #include <java/lang/Thread.h>
 | |
| #include <java/io/InterruptedIOException.h>
 | |
| #include <java/util/Properties.h>
 | |
| 
 | |
| #if defined (ECOS)
 | |
| extern "C" unsigned long long _clock (void);
 | |
| #endif
 | |
| 
 | |
| #if defined(HAVE_PROC_SELF_EXE)
 | |
| static char exec_name[20];
 | |
|   // initialized in _Jv_platform_initialize()
 | |
| #endif
 | |
| 
 | |
| const char *_Jv_ThisExecutable (void)
 | |
| {
 | |
| #if defined(DISABLE_MAIN_ARGS)
 | |
|   return "[Embedded App]";
 | |
| #elif defined(HAVE_PROC_SELF_EXE)
 | |
|   return exec_name;
 | |
|     // initialized in _Jv_platform_initialize()
 | |
| #else
 | |
|   return _Jv_GetSafeArg (0);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| // gettimeofday implementation.
 | |
| jlong
 | |
| _Jv_platform_gettimeofday ()
 | |
| {
 | |
| #if defined (HAVE_GETTIMEOFDAY)
 | |
|   timeval tv;
 | |
|   gettimeofday (&tv, NULL);
 | |
|   return (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL);
 | |
| #elif defined (HAVE_TIME)
 | |
|   return time (NULL) * 1000LL;
 | |
| #elif defined (HAVE_FTIME)
 | |
|   struct timeb t;
 | |
|   ftime (&t);
 | |
|   return (t.time * 1000LL) + t.millitm;
 | |
| #elif defined (ECOS)
 | |
|   // FIXME.
 | |
|   return _clock();
 | |
| #else
 | |
|   // In the absence of any function, time remains forever fixed.
 | |
|   return 23000;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| jlong
 | |
| _Jv_platform_nanotime ()
 | |
| {
 | |
| #ifdef HAVE_CLOCK_GETTIME
 | |
|   struct timespec now;
 | |
|   clockid_t id;
 | |
| #ifdef CLOCK_MONOTONIC
 | |
|   id = CLOCK_MONOTONIC;
 | |
| #elif defined (CLOCK_HIGHRES)
 | |
|   id = CLOCK_HIGHRES;
 | |
| #else
 | |
|   id = CLOCK_REALTIME;
 | |
| #endif
 | |
|   if (clock_gettime (id, &now) == 0)
 | |
|     {
 | |
|       jlong result = (jlong) now.tv_sec;
 | |
|       result = result * 1000000000LL + now.tv_nsec;
 | |
|       return result;
 | |
|     }
 | |
|   // clock_gettime failed, but we can fall through.
 | |
| #endif // HAVE_CLOCK_GETTIME
 | |
| #if defined (HAVE_GETTIMEOFDAY)
 | |
|  {
 | |
|    timeval tv;
 | |
|    gettimeofday (&tv, NULL);
 | |
|    return (tv.tv_sec * 1000000000LL) + tv.tv_usec * 1000LL;
 | |
|  }
 | |
| #else
 | |
|   return _Jv_platform_gettimeofday () * 1000000LL;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| // Platform-specific VM initialization.
 | |
| void
 | |
| _Jv_platform_initialize (void)
 | |
| {
 | |
| #if defined (HAVE_SIGACTION)
 | |
|   // We only want this on POSIX systems.
 | |
|   struct sigaction act;
 | |
|   act.sa_handler = SIG_IGN;
 | |
|   sigemptyset (&act.sa_mask);
 | |
|   act.sa_flags = 0;
 | |
|   sigaction (SIGPIPE, &act, NULL);
 | |
| #else
 | |
|   signal (SIGPIPE, SIG_IGN);
 | |
| #endif
 | |
| 
 | |
| #if defined (HAVE_PROC_SELF_EXE)
 | |
|   // Compute our executable name
 | |
|   sprintf (exec_name, "/proc/%d/exe", getpid ());
 | |
| #endif
 | |
| }
 | |
| 
 | |
| // Set platform-specific System properties.
 | |
| void
 | |
| _Jv_platform_initProperties (java::util::Properties* newprops)
 | |
| {
 | |
|   // A convenience define.
 | |
| #define SET(Prop,Val) \
 | |
|   newprops->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
 | |
| 
 | |
|   SET ("file.separator", "/");
 | |
|   SET ("path.separator", ":");
 | |
|   SET ("line.separator", "\n");
 | |
|   const char *tmpdir = ::getenv("TMPDIR");
 | |
|   if (! tmpdir)
 | |
|     tmpdir = "/tmp";
 | |
|   SET ("java.io.tmpdir", tmpdir);
 | |
|   const char *zoneinfodir = ::getenv("TZDATA");
 | |
|   if (! zoneinfodir)
 | |
|     zoneinfodir = "/usr/share/zoneinfo";
 | |
|   SET ("gnu.java.util.zoneinfo.dir", zoneinfodir);
 | |
| }
 | |
| 
 | |
| static inline void
 | |
| internal_gettimeofday (struct timeval *result)
 | |
| {
 | |
| #if defined (HAVE_GETTIMEOFDAY)
 | |
|   gettimeofday (result, NULL);
 | |
| #else
 | |
|   jlong val = _Jv_platform_gettimeofday ();
 | |
|   result->tv_sec = val / 1000;
 | |
|   result->tv_usec = (val % 1000) * 1000;
 | |
| #endif /* HAVE_GETTIMEOFDAY */
 | |
| }
 | |
| 
 | |
| // A wrapper for select() which ignores EINTR.
 | |
| int
 | |
| _Jv_select (int n, fd_set *readfds, fd_set  *writefds,
 | |
| 	    fd_set *exceptfds, struct timeval *timeout)
 | |
| {
 | |
| #ifdef HAVE_SELECT
 | |
|   // If we have a timeout, compute the absolute ending time.
 | |
|   struct timeval end, delay;
 | |
|   if (timeout)
 | |
|     {
 | |
|       internal_gettimeofday (&end);
 | |
|       end.tv_usec += timeout->tv_usec;
 | |
|       if (end.tv_usec >= 1000000)
 | |
| 	{
 | |
| 	  ++end.tv_sec;
 | |
| 	  end.tv_usec -= 1000000;
 | |
| 	}
 | |
|       end.tv_sec += timeout->tv_sec;
 | |
|       delay = *timeout;
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       // Placate compiler.
 | |
|       delay.tv_sec = delay.tv_usec = 0;
 | |
|     }
 | |
| 
 | |
|   while (1)
 | |
|     {
 | |
|       int r = select (n, readfds, writefds, exceptfds,
 | |
| 		      timeout ? &delay : NULL);
 | |
|       if (r != -1 || errno != EINTR)
 | |
| 	return r;
 | |
| 
 | |
|       // Here we know we got EINTR.
 | |
|       if (java::lang::Thread::interrupted ())
 | |
| 	throw new java::io::InterruptedIOException (JvNewStringLatin1 ("select interrupted"));
 | |
| 
 | |
|       struct timeval after;
 | |
|       if (timeout)
 | |
| 	{
 | |
| 	  internal_gettimeofday (&after);
 | |
| 	  // Now compute new timeout argument.
 | |
| 	  delay.tv_usec = end.tv_usec - after.tv_usec;
 | |
| 	  delay.tv_sec = end.tv_sec - after.tv_sec;
 | |
| 	  if (delay.tv_usec < 0)
 | |
| 	    {
 | |
| 	      --delay.tv_sec;
 | |
| 	      delay.tv_usec += 1000000;
 | |
| 	    }
 | |
| 	  if (delay.tv_sec < 0)
 | |
| 	    {
 | |
| 	      // We assume that the user wants a valid select() call
 | |
| 	      // more than precise timing.  So if we get a series of
 | |
| 	      // EINTR we just keep trying with delay 0 until we get a
 | |
| 	      // valid result.
 | |
| 	      delay.tv_sec = 0;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| #else /* HAVE_SELECT */
 | |
|   return 0;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| // Given an address, find the object that defines it and the nearest
 | |
| // defined symbol to that address.  Returns 0 if no object defines this
 | |
| // address.
 | |
| int
 | |
| _Jv_platform_dladdr (void *addr, _Jv_AddrInfo *info)
 | |
| {
 | |
|   int ret_val = 0;
 | |
| 
 | |
| #if defined (HAVE_DLFCN_H) && defined (HAVE_DLADDR)
 | |
|   Dl_info addr_info;
 | |
|   ret_val = dladdr (addr, &addr_info);
 | |
|   if (ret_val != 0)
 | |
|     {
 | |
|       info->file_name = addr_info.dli_fname;
 | |
|       info->base = addr_info.dli_fbase;
 | |
|       info->sym_name = addr_info.dli_sname;
 | |
|       info->sym_addr = addr_info.dli_saddr;
 | |
|     }
 | |
| #else
 | |
|   info->file_name = NULL;
 | |
|   info->base = NULL;
 | |
|   info->sym_name = NULL;
 | |
|   info->sym_addr = NULL;
 | |
| #endif
 | |
| 
 | |
|   return ret_val;
 | |
| }
 |