// -*- C++ -*- #include "ace/OS_NS_sys_utsname.h" #include "ace/OS_NS_string.h" #include "ace/OS_NS_errno.h" #include "ace/OS_NS_macros.h" #include "ace/OS_NS_fcntl.h" #include "ace/Default_Constants.h" #include "ace/OS_Memory.h" #include "ace/Truncate.h" #if defined (ACE_HAS_CLOCK_GETTIME) # include "ace/os_include/os_time.h" #endif /* ACE_HAS_CLOCK_GETTIME */ #if defined (ACE_LACKS_ACCESS) # include "ace/OS_NS_stdio.h" #endif /* ACE_LACKS_ACCESS */ #if defined (ACE_HAS_ACCESS_EMULATION) # include "ace/os_include/os_unistd.h" #endif /* ACE_HAS_ACCESS_EMULATION */ #if defined (ACE_VXWORKS) && (ACE_VXWORKS <= 0x690) # if defined (__RTP__) # include "ace/os_include/os_strings.h" # else # include "ace/os_include/os_string.h" # endif #endif ACE_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE int ACE_OS::access (const char *path, int amode) { ACE_OS_TRACE ("ACE_OS::access"); #if defined (ACE_LACKS_ACCESS) # if defined (ACE_HAS_ACCESS_EMULATION) // @@ WINCE: There should be a Win32 API that can do this. // Hard coded read access here. ACE_UNUSED_ARG (amode); FILE* handle = ACE_OS::fopen (ACE_TEXT_CHAR_TO_TCHAR(path), ACE_TEXT ("r")); if (handle != 0) { ACE_OS::fclose (handle); return 0; } return -1; # else ACE_UNUSED_ARG (path); ACE_UNUSED_ARG (amode); ACE_NOTSUP_RETURN (-1); # endif /* ACE_HAS_ACCESS_EMULATION */ #elif defined(ACE_WIN32) // Windows doesn't support checking X_OK(6) # if defined (ACE_ACCESS_EQUIVALENT) ACE_OSCALL_RETURN (ACE_ACCESS_EQUIVALENT (path, amode & 6), int, -1); # else ACE_OSCALL_RETURN (::access (path, amode & 6), int, -1); # endif #else ACE_OSCALL_RETURN (::access (path, amode), int, -1); #endif /* ACE_LACKS_ACCESS */ } #if defined (ACE_HAS_WCHAR) ACE_INLINE int ACE_OS::access (const wchar_t *path, int amode) { #if defined (ACE_WIN32) && !defined (ACE_LACKS__WACCESS) ACE_OSCALL_RETURN (::_waccess (path, amode), int, -1); #else /* ACE_WIN32 && !ACE_HAS_WINCE */ return ACE_OS::access (ACE_Wide_To_Ascii (path).char_rep (), amode); #endif /* ACE_WIN32 && !ACE_LACKS__WACCESS */ } #endif /* ACE_HAS_WCHAR */ ACE_INLINE u_int ACE_OS::alarm (u_int secs) { ACE_OS_TRACE ("ACE_OS::alarm"); #if defined (ACE_LACKS_ALARM) ACE_UNUSED_ARG (secs); ACE_NOTSUP_RETURN (0); #else return ::alarm (secs); #endif /* ACE_LACKS_ALARM */ } ACE_INLINE long ACE_OS::getpagesize (void) { ACE_OS_TRACE ("ACE_OS::getpagesize"); #if defined (ACE_WIN32) && !defined (ACE_HAS_PHARLAP) SYSTEM_INFO sys_info; ::GetSystemInfo (&sys_info); return (long) sys_info.dwPageSize; #elif defined (_SC_PAGESIZE) && !defined (ACE_HAS_NOTSUP_SC_PAGESIZE) return ::sysconf (_SC_PAGESIZE); #elif defined (ACE_HAS_GETPAGESIZE) return ::getpagesize (); #else // Use the default set in config.h return ACE_PAGE_SIZE; #endif /* ACE_WIN32 */ } ACE_INLINE long ACE_OS::allocation_granularity (void) { #if defined (ACE_WIN32) SYSTEM_INFO sys_info; ::GetSystemInfo (&sys_info); return sys_info.dwAllocationGranularity; #else return ACE_OS::getpagesize (); #endif /* ACE_WIN32 */ } ACE_INLINE int ACE_OS::chdir (const char *path) { ACE_OS_TRACE ("ACE_OS::chdir"); #if defined (ACE_LACKS_CHDIR) ACE_UNUSED_ARG (path); ACE_NOTSUP_RETURN (-1); #elif defined (ACE_HAS_NONCONST_CHDIR) ACE_OSCALL_RETURN (::chdir (const_cast (path)), int, -1); #elif defined (ACE_CHDIR_EQUIVALENT) ACE_OSCALL_RETURN (ACE_CHDIR_EQUIVALENT (path), int, -1); #else ACE_OSCALL_RETURN (::chdir (path), int, -1); #endif /* ACE_HAS_NONCONST_CHDIR */ } #if defined (ACE_HAS_WCHAR) ACE_INLINE int ACE_OS::chdir (const wchar_t *path) { #if defined (ACE_LACKS_CHDIR) ACE_UNUSED_ARG (path); ACE_NOTSUP_RETURN (-1); #elif defined (ACE_WIN32) ACE_OSCALL_RETURN (::_wchdir (path), int, -1); #else /* ACE_WIN32 */ return ACE_OS::chdir (ACE_Wide_To_Ascii (path).char_rep ()); #endif /* ACE_WIN32 */ } #endif /* ACE_HAS_WCHAR */ ACE_INLINE int ACE_OS::rmdir (const char *path) { #if defined (ACE_HAS_WINCE) ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::RemoveDirectory (ACE_TEXT_CHAR_TO_TCHAR(path)), ace_result_), int, -1); #elif defined (ACE_RMDIR_EQUIVALENT) ACE_OSCALL_RETURN (ACE_RMDIR_EQUIVALENT (path), int, -1); #else ACE_OSCALL_RETURN (::rmdir (path), int, -1); #endif /* ACE_WIN32 */ } #if defined (ACE_HAS_WCHAR) ACE_INLINE int ACE_OS::rmdir (const wchar_t *path) { #if defined (ACE_HAS_WINCE) ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::RemoveDirectoryW (path), ace_result_), int, -1); #elif defined (ACE_WIN32) ACE_OSCALL_RETURN (::_wrmdir (path), int, -1); #else ACE_Wide_To_Ascii n_path (path); return ACE_OS::rmdir (n_path.char_rep ()); #endif /* ACE_HAS_WINCE */ } #endif /* ACE_HAS_WCHAR */ // @todo: which 4 and why??? dhinton // NOTE: The following four function definitions must appear before // ACE_OS::sema_init (). ACE_INLINE int ACE_OS::close (ACE_HANDLE handle) { ACE_OS_TRACE ("ACE_OS::close"); #if defined (ACE_WIN32) ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CloseHandle (handle), ace_result_), int, -1); #else ACE_OSCALL_RETURN (::close (handle), int, -1); #endif /* ACE_WIN32 */ } ACE_INLINE ACE_HANDLE ACE_OS::dup (ACE_HANDLE handle) { ACE_OS_TRACE ("ACE_OS::dup"); #if defined (ACE_LACKS_DUP) ACE_UNUSED_ARG (handle); ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE); #elif defined (ACE_WIN32) ACE_HANDLE new_fd; if (::DuplicateHandle(::GetCurrentProcess (), handle, ::GetCurrentProcess(), &new_fd, 0, TRUE, DUPLICATE_SAME_ACCESS)) return new_fd; else ACE_FAIL_RETURN (ACE_INVALID_HANDLE); /* NOTREACHED */ #else ACE_OSCALL_RETURN (::dup (handle), ACE_HANDLE, ACE_INVALID_HANDLE); #endif /* ACE_LACKS_DUP */ } ACE_INLINE ACE_HANDLE ACE_OS::dup(ACE_HANDLE handle, pid_t pid) { ACE_OS_TRACE("ACE_OS::dup"); #if defined (ACE_LACKS_DUP) ACE_UNUSED_ARG (handle); ACE_UNUSED_ARG (pid); ACE_NOTSUP_RETURN (ACE_INVALID_HANDLE); #elif defined (ACE_WIN32) ACE_HANDLE new_fd; ACE_HANDLE hTargetProcess = ::OpenProcess (PROCESS_DUP_HANDLE, FALSE, pid); if(::DuplicateHandle(::GetCurrentProcess (), handle, hTargetProcess, &new_fd, 0, TRUE, DUPLICATE_SAME_ACCESS)) { ::CloseHandle (hTargetProcess); return new_fd; } else ACE_FAIL_RETURN (ACE_INVALID_HANDLE); /*NOTREACHED*/ #else ACE_UNUSED_ARG (pid); ACE_OSCALL_RETURN(::dup(handle), ACE_HANDLE, ACE_INVALID_HANDLE); #endif /*ACE_WIN32 && !ACE_HAS_WINCE*/ } ACE_INLINE int ACE_OS::dup2 (ACE_HANDLE oldhandle, ACE_HANDLE newhandle) { ACE_OS_TRACE ("ACE_OS::dup2"); #if defined (ACE_LACKS_DUP2) // msvcrt has _dup2 ?! ACE_UNUSED_ARG (oldhandle); ACE_UNUSED_ARG (newhandle); ACE_NOTSUP_RETURN (-1); #else ACE_OSCALL_RETURN (::dup2 (oldhandle, newhandle), int, -1); #endif /* ACE_LACKS_DUP2 */ } ACE_INLINE int ACE_OS::execv (const char *path, char *const argv[]) { ACE_OS_TRACE ("ACE_OS::execv"); #if defined (ACE_LACKS_EXEC) ACE_UNUSED_ARG (path); ACE_UNUSED_ARG (argv); ACE_NOTSUP_RETURN (-1); #elif defined (ACE_WIN32) # if defined (__BORLANDC__) return ::execv (path, argv); # elif defined (__MINGW32__) return ::_execv (path, (char *const *) argv); # else // Why this odd-looking code? If execv() returns at all, it's an error. // Windows defines this as returning an intptr_t rather than a simple int, // and the conversion triggers compile warnings. So just return -1 if // the call returns. ::_execv (path, (const char *const *) argv); return -1; # endif /* __BORLANDC__ */ #else ACE_OSCALL_RETURN (::execv (path, argv), int, -1); #endif /* ACE_LACKS_EXEC */ } ACE_INLINE int ACE_OS::execve (const char *path, char *const argv[], char *const envp[]) { ACE_OS_TRACE ("ACE_OS::execve"); #if defined (ACE_LACKS_EXEC) ACE_UNUSED_ARG (path); ACE_UNUSED_ARG (argv); ACE_UNUSED_ARG (envp); ACE_NOTSUP_RETURN (-1); #elif defined (ACE_WIN32) # if defined (__BORLANDC__) return ::execve (path, argv, envp); # elif defined (__MINGW32__) return ::_execve (path, (char *const *) argv, (char *const *) envp); # else // Why this odd-looking code? If execv() returns at all, it's an error. // Windows defines this as returning an intptr_t rather than a simple int, // and the conversion triggers compile warnings. So just return -1 if // the call returns. ::_execve (path, (const char *const *) argv, (const char *const *) envp); return -1; # endif /* __BORLANDC__ */ #else ACE_OSCALL_RETURN (::execve (path, argv, envp), int, -1); #endif /* ACE_LACKS_EXEC */ } ACE_INLINE int ACE_OS::execvp (const char *file, char *const argv[]) { ACE_OS_TRACE ("ACE_OS::execvp"); #if defined (ACE_LACKS_EXEC) ACE_UNUSED_ARG (file); ACE_UNUSED_ARG (argv); ACE_NOTSUP_RETURN (-1); #elif defined (ACE_WIN32) # if defined (__BORLANDC__) return ::execvp (file, argv); # elif defined (__MINGW32__) return ::_execvp (file, (char *const *) argv); # else // Why this odd-looking code? If execv() returns at all, it's an error. // Windows defines this as returning an intptr_t rather than a simple int, // and the conversion triggers compile warnings. So just return -1 if // the call returns. ::_execvp (file, (const char *const *) argv); return -1; # endif /* __BORLANDC__ */ #else ACE_OSCALL_RETURN (::execvp (file, argv), int, -1); #endif /* ACE_LACKS_EXEC */ } ACE_INLINE pid_t ACE_OS::fork (void) { ACE_OS_TRACE ("ACE_OS::fork"); #if defined (ACE_LACKS_FORK) ACE_NOTSUP_RETURN (pid_t (-1)); #else ACE_OSCALL_RETURN (::fork (), pid_t, -1); #endif /* ACE_LACKS_FORK */ } ACE_INLINE int ACE_OS::fsync (ACE_HANDLE handle) { ACE_OS_TRACE ("ACE_OS::fsync"); # if defined (ACE_LACKS_FSYNC) ACE_UNUSED_ARG (handle); ACE_NOTSUP_RETURN (-1); # elif defined (ACE_WIN32) ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::FlushFileBuffers (handle), ace_result_), int, -1); # else ACE_OSCALL_RETURN (::fsync (handle), int, -1); # endif /* ACE_LACKS_FSYNC */ } ACE_INLINE int ACE_OS::ftruncate (ACE_HANDLE handle, ACE_OFF_T offset) { ACE_OS_TRACE ("ACE_OS::ftruncate"); #if defined (ACE_WIN32) # if !defined (ACE_LACKS_WIN32_SETFILEPOINTEREX) LARGE_INTEGER loff; loff.QuadPart = offset; if (::SetFilePointerEx (handle, loff, 0, FILE_BEGIN)) # else if (::SetFilePointer (handle, offset, 0, FILE_BEGIN) != INVALID_SET_FILE_POINTER) # endif ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::SetEndOfFile (handle), ace_result_), int, -1); else ACE_FAIL_RETURN (-1); #else ACE_OSCALL_RETURN (::ftruncate (handle, offset), int, -1); #endif /* ACE_WIN32 */ } ACE_INLINE char * ACE_OS::getcwd (char *buf, size_t size) { ACE_OS_TRACE ("ACE_OS::getcwd"); #if defined (ACE_LACKS_GETCWD) ACE_UNUSED_ARG (buf); ACE_UNUSED_ARG (size); ACE_NOTSUP_RETURN (0); #elif defined (ACE_WIN32) # if defined (ACE_GETCWD_EQUIVALENT) return ACE_GETCWD_EQUIVALENT (buf, static_cast (size)); # else return ::getcwd (buf, static_cast (size)); # endif #else ACE_OSCALL_RETURN (::getcwd (buf, size), char *, 0); #endif /* ACE_LACKS_GETCWD */ } #if defined (ACE_HAS_WCHAR) ACE_INLINE wchar_t * ACE_OS::getcwd (wchar_t *buf, size_t size) { # if defined (ACE_HAS_WINCE) ACE_UNUSED_ARG (buf); ACE_UNUSED_ARG (size); ACE_NOTSUP_RETURN (0); # elif defined (ACE_WIN32) return ::_wgetcwd (buf, static_cast (size)); # else char *narrow_buf = new char[size]; char *result = 0; result = ACE_OS::getcwd (narrow_buf, size); ACE_Ascii_To_Wide wide_buf (result); delete [] narrow_buf; if (result != 0) ACE_OS::strsncpy (buf, wide_buf.wchar_rep (), size); return result == 0 ? 0 : buf; # endif /* ACE_WIN32 */ } #endif /* ACE_HAS_WCHAR */ ACE_INLINE gid_t ACE_OS::getgid (void) { ACE_OS_TRACE ("ACE_OS::getgid"); #if defined (ACE_LACKS_GETGID) ACE_NOTSUP_RETURN (static_cast (-1)); # else ACE_OSCALL_RETURN (::getgid (), gid_t, static_cast (-1)); # endif /* ACE_LACKS_GETGID */ } ACE_INLINE gid_t ACE_OS::getegid (void) { ACE_OS_TRACE ("ACE_OS::getegid"); #if defined (ACE_LACKS_GETEGID) ACE_NOTSUP_RETURN (static_cast (-1)); # else ACE_OSCALL_RETURN (::getegid (), gid_t, static_cast (-1)); # endif /* ACE_LACKS_GETEGID */ } ACE_INLINE int ACE_OS::getopt (int argc, char *const *argv, const char *optstring) { ACE_OS_TRACE ("ACE_OS::getopt"); #if defined (ACE_LACKS_GETOPT) ACE_UNUSED_ARG (argc); ACE_UNUSED_ARG (argv); ACE_UNUSED_ARG (optstring); ACE_NOTSUP_RETURN (-1); # else ACE_OSCALL_RETURN (::getopt (argc, argv, optstring), int, -1); # endif /* ACE_LACKS_GETOPT */ } ACE_INLINE pid_t ACE_OS::getpgid (pid_t pid) { ACE_OS_TRACE ("ACE_OS::getpgid"); #if defined (ACE_LACKS_GETPGID) ACE_UNUSED_ARG (pid); ACE_NOTSUP_RETURN (-1); #elif defined (ACE_LINUX) && __GLIBC__ > 1 && __GLIBC_MINOR__ >= 0 // getpgid() is from SVR4, which appears to be the reason why GLIBC // doesn't enable its prototype by default. // Rather than create our own extern prototype, just use the one // that is visible (ugh). ACE_OSCALL_RETURN (::__getpgid (pid), pid_t, -1); #else ACE_OSCALL_RETURN (::getpgid (pid), pid_t, -1); #endif /* ACE_LACKS_GETPGID */ } ACE_INLINE pid_t ACE_OS::getpid (void) { // ACE_OS_TRACE ("ACE_OS::getpid"); #if defined (ACE_LACKS_GETPID) ACE_NOTSUP_RETURN (-1); #elif defined (ACE_WIN32) return ::GetCurrentProcessId (); #else ACE_OSCALL_RETURN (::getpid (), pid_t, -1); #endif /* ACE_LACKS_GETPID */ } ACE_INLINE pid_t ACE_OS::getppid (void) { ACE_OS_TRACE ("ACE_OS::getppid"); #if defined (ACE_LACKS_GETPPID) ACE_NOTSUP_RETURN (-1); #else ACE_OSCALL_RETURN (::getppid (), pid_t, -1); #endif /* ACE_LACKS_GETPPID */ } ACE_INLINE uid_t ACE_OS::getuid (void) { ACE_OS_TRACE ("ACE_OS::getuid"); #if defined (ACE_LACKS_GETUID) ACE_NOTSUP_RETURN (static_cast (-1)); # else ACE_OSCALL_RETURN (::getuid (), uid_t, static_cast (-1)); # endif /* ACE_LACKS_GETUID*/ } ACE_INLINE uid_t ACE_OS::geteuid (void) { ACE_OS_TRACE ("ACE_OS::geteuid"); #if defined (ACE_LACKS_GETEUID) ACE_NOTSUP_RETURN (static_cast (-1)); # else ACE_OSCALL_RETURN (::geteuid (), uid_t, (uid_t) -1); # endif /* ACE_LACKS_GETEUID */ } ACE_INLINE int ACE_OS::hostname (char name[], size_t maxnamelen) { ACE_OS_TRACE ("ACE_OS::hostname"); #if defined (ACE_HAS_PHARLAP) // PharLap only can do net stuff with the RT version. # if defined (ACE_HAS_PHARLAP_RT) // @@This is not at all reliable... requires ethernet and BOOTP to be used. // A more reliable way is to go thru the devices w/ EtsTCPGetDeviceCfg until // a legit IP address is found, then get its name w/ gethostbyaddr. ACE_SOCKCALL_RETURN (gethostname (name, maxnamelen), int, SOCKET_ERROR); # else ACE_UNUSED_ARG (name); ACE_UNUSED_ARG (maxnamelen); ACE_NOTSUP_RETURN (-1); # endif /* ACE_HAS_PHARLAP_RT */ #elif defined (ACE_VXWORKS) || defined (ACE_HAS_WINCE) ACE_OSCALL_RETURN (::gethostname (name, maxnamelen), int, -1); #elif defined (ACE_WIN32) if (::gethostname (name, ACE_Utils::truncate_cast (maxnamelen)) == 0) { return 0; } else { ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::GetComputerNameA (name, LPDWORD (&maxnamelen)), ace_result_), int, -1); } #else /* ACE_HAS_PHARLAP */ ACE_utsname host_info; if (ACE_OS::uname (&host_info) == -1) return -1; else { ACE_OS::strsncpy (name, host_info.nodename, maxnamelen); return 0; } #endif /* ACE_HAS_PHARLAP */ } #if defined (ACE_HAS_WCHAR) ACE_INLINE int ACE_OS::hostname (wchar_t name[], size_t maxnamelen) { #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (GetComputerNameW (name, LPDWORD (&maxnamelen)), ace_result_), int, -1); #else /* ACE_WIN32 && !ACE_HAS_WINCE */ // Emulate using the char version char *char_name = 0; ACE_NEW_RETURN (char_name, char[maxnamelen], -1); int result = ACE_OS::hostname(char_name, maxnamelen); ACE_OS::strcpy (name, ACE_Ascii_To_Wide (char_name).wchar_rep ()); delete [] char_name; return result; #endif /* ACE_WIN32 && !ACE_HAS_WINCE */ } #endif /* ACE_HAS_WCHAR */ ACE_INLINE int ACE_OS::isatty (int handle) { ACE_OS_TRACE ("ACE_OS::isatty"); #if defined (ACE_LACKS_ISATTY) ACE_UNUSED_ARG (handle); return 0; # elif defined (ACE_WIN32) return ::_isatty (handle); # else ACE_OSCALL_RETURN (::isatty (handle), int, -1); # endif /* ACE_LACKS_ISATTY */ } #if defined (ACE_WIN32) ACE_INLINE int ACE_OS::isatty (ACE_HANDLE handle) { #if defined (ACE_LACKS_ISATTY) ACE_UNUSED_ARG (handle); return 0; #else int const fd = ::_open_osfhandle (intptr_t (handle), 0); int status = 0; if (fd != -1) { status = ::_isatty (fd); ::_close (fd); } return status; #endif /* ACE_LACKS_ISATTY */ } #endif /* ACE_WIN32 */ ACE_INLINE ACE_OFF_T ACE_OS::lseek (ACE_HANDLE handle, ACE_OFF_T offset, int whence) { ACE_OS_TRACE ("ACE_OS::lseek"); #if defined (ACE_WIN32) # if SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END //#error Windows NT is evil AND rude! switch (whence) { case SEEK_SET: whence = FILE_BEGIN; break; case SEEK_CUR: whence = FILE_CURRENT; break; case SEEK_END: whence = FILE_END; break; default: errno = EINVAL; return static_cast (-1); // rather safe than sorry } # endif /* SEEK_SET != FILE_BEGIN || SEEK_CUR != FILE_CURRENT || SEEK_END != FILE_END */ LONG low_offset = ACE_LOW_PART(offset); LONG high_offset = ACE_HIGH_PART(offset); DWORD const result = ::SetFilePointer (handle, low_offset, &high_offset, whence); if (result == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) ACE_FAIL_RETURN (static_cast (-1)); else return result; #else ACE_OSCALL_RETURN (::lseek (handle, offset, whence), ACE_OFF_T, -1); #endif /* ACE_WIN32 */ } #if defined (ACE_HAS_LLSEEK) || defined (ACE_HAS_LSEEK64) ACE_INLINE ACE_LOFF_T ACE_OS::llseek (ACE_HANDLE handle, ACE_LOFF_T offset, int whence) { ACE_OS_TRACE ("ACE_OS::llseek"); #if ACE_SIZEOF_LONG == 8 /* The native lseek is 64 bit. Use it. */ return ACE_OS::lseek (handle, offset, whence); #elif defined (ACE_HAS_LLSEEK) && defined (ACE_HAS_LSEEK64) # error Either ACE_HAS_LSEEK64 and ACE_HAS_LLSEEK should be defined, not both! #elif defined (ACE_HAS_LSEEK64) ACE_OSCALL_RETURN (::lseek64 (handle, offset, whence), ACE_LOFF_T, -1); #elif defined (ACE_HAS_LLSEEK) # if defined (ACE_WIN32) # ifndef ACE_LACKS_WIN32_SETFILEPOINTEREX LARGE_INTEGER distance, new_file_pointer; distance.QuadPart = offset; return (::SetFilePointerEx (handle, distance, &new_file_pointer, whence) ? new_file_pointer.QuadPart : static_cast (-1)); # else LARGE_INTEGER l_offset; l_offset.QuadPart = offset; LONG low_offset = l_offset.LowPart; LONG high_offset = l_offset.HighPart; l_offset.LowPart = ::SetFilePointer (handle, low_offset, &high_offset, whence); if (l_offset.LowPart == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) return static_cast (-1); l_offset.HighPart = high_offset; return l_offset.QuadPart; # endif /* ACE_LACKS_WIN32_SETFILEPOINTEREX */ # else ACE_OSCALL_RETURN (::llseek (handle, offset, whence), ACE_LOFF_T, -1); # endif /* WIN32 */ #endif } #endif /* ACE_HAS_LLSEEK || ACE_HAS_LSEEK64 */ ACE_INLINE ssize_t ACE_OS::read (ACE_HANDLE handle, void *buf, size_t len) { ACE_OS_TRACE ("ACE_OS::read"); #if defined (ACE_WIN32) DWORD ok_len; if (::ReadFile (handle, buf, static_cast (len), &ok_len, 0)) return (ssize_t) ok_len; else ACE_FAIL_RETURN (-1); #else ssize_t result; # if defined (ACE_HAS_CHARPTR_SOCKOPT) ACE_OSCALL (::read (handle, static_cast (buf), len), ssize_t, -1, result); # else ACE_OSCALL (::read (handle, buf, len), ssize_t, -1, result); # endif /* ACE_HAS_CHARPTR_SOCKOPT */ # if !(defined (EAGAIN) && defined (EWOULDBLOCK) && EAGAIN == EWOULDBLOCK) // Optimize this code out if we can detect that EAGAIN == // EWOULDBLOCK at compile time. If we cannot detect equality at // compile-time (e.g. if EAGAIN or EWOULDBLOCK are not preprocessor // macros) perform the check at run-time. The goal is to avoid two // TSS accesses in the _REENTRANT case when EAGAIN == EWOULDBLOCK. if (result == -1 # if !defined (EAGAIN) || !defined (EWOULDBLOCK) && EAGAIN != EWOULDBLOCK # endif /* !EAGAIN || !EWOULDBLOCK */ && errno == EAGAIN) { errno = EWOULDBLOCK; } # endif /* EAGAIN != EWOULDBLOCK*/ return result; #endif /* ACE_WIN32 */ } ACE_INLINE ssize_t ACE_OS::read (ACE_HANDLE handle, void *buf, size_t len, ACE_OVERLAPPED *overlapped) { ACE_OS_TRACE ("ACE_OS::read"); #if defined (ACE_WIN32) DWORD ok_len; DWORD short_len = static_cast (len); if (::ReadFile (handle, buf, short_len, &ok_len, overlapped)) return (ssize_t) ok_len; else ACE_FAIL_RETURN (-1); #else ACE_UNUSED_ARG (overlapped); return ACE_OS::read (handle, buf, len); #endif /* ACE_WIN32 */ } ACE_INLINE ssize_t ACE_OS::readlink (const char *path, char *buf, size_t bufsiz) { ACE_OS_TRACE ("ACE_OS::readlink"); # if defined (ACE_LACKS_READLINK) ACE_UNUSED_ARG (path); ACE_UNUSED_ARG (buf); ACE_UNUSED_ARG (bufsiz); ACE_NOTSUP_RETURN (-1); # elif defined(ACE_HAS_NONCONST_READLINK) ACE_OSCALL_RETURN ( ::readlink (const_cast (path), buf, bufsiz), ssize_t, -1); # else ACE_OSCALL_RETURN (::readlink (path, buf, bufsiz), ssize_t, -1); # endif /* ACE_LACKS_READLINK */ } ACE_INLINE int ACE_OS::pipe (ACE_HANDLE fds[]) { ACE_OS_TRACE ("ACE_OS::pipe"); # if defined (ACE_LACKS_PIPE) ACE_UNUSED_ARG (fds); ACE_NOTSUP_RETURN (-1); # elif defined (ACE_WIN32) ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::CreatePipe (&fds[0], &fds[1], 0, 0), ace_result_), int, -1); # else ACE_OSCALL_RETURN (::pipe (fds), int, -1); # endif /* ACE_LACKS_PIPE */ } ACE_INLINE void * ACE_OS::sbrk (intptr_t brk) { #if defined (ACE_LACKS_SBRK) ACE_UNUSED_ARG (brk); ACE_NOTSUP_RETURN (0); #else ACE_OSCALL_RETURN (::sbrk (brk), void *, 0); #endif /* ACE_LACKS_SBRK */ } ACE_INLINE int ACE_OS::setgid (gid_t gid) { ACE_OS_TRACE ("ACE_OS::setgid"); #if defined (ACE_LACKS_SETGID) ACE_UNUSED_ARG (gid); ACE_NOTSUP_RETURN (-1); # else ACE_OSCALL_RETURN (::setgid (gid), int, -1); # endif /* ACE_LACKS_SETGID */ } ACE_INLINE int ACE_OS::setegid (gid_t gid) { ACE_OS_TRACE ("ACE_OS::setegid"); #if defined (ACE_LACKS_SETEGID) ACE_UNUSED_ARG (gid); ACE_NOTSUP_RETURN (-1); # else ACE_OSCALL_RETURN (::setegid (gid), int, -1); # endif /* ACE_LACKS_SETEGID */ } ACE_INLINE int ACE_OS::setpgid (pid_t pid, pid_t pgid) { ACE_OS_TRACE ("ACE_OS::setpgid"); #if defined (ACE_LACKS_SETPGID) ACE_UNUSED_ARG (pid); ACE_UNUSED_ARG (pgid); ACE_NOTSUP_RETURN (-1); #else ACE_OSCALL_RETURN (::setpgid (pid, pgid), int, -1); #endif /* ACE_LACKS_SETPGID */ } ACE_INLINE int ACE_OS::setregid (gid_t rgid, gid_t egid) { ACE_OS_TRACE ("ACE_OS::setregid"); #if defined (ACE_LACKS_SETREGID) ACE_UNUSED_ARG (rgid); ACE_UNUSED_ARG (egid); ACE_NOTSUP_RETURN (-1); #else ACE_OSCALL_RETURN (::setregid (rgid, egid), int, -1); #endif /* ACE_LACKS_SETREGID */ } ACE_INLINE int ACE_OS::setreuid (uid_t ruid, uid_t euid) { ACE_OS_TRACE ("ACE_OS::setreuid"); #if defined (ACE_LACKS_SETREUID) ACE_UNUSED_ARG (ruid); ACE_UNUSED_ARG (euid); ACE_NOTSUP_RETURN (-1); #else ACE_OSCALL_RETURN (::setreuid (ruid, euid), int, -1); #endif /* ACE_LACKS_SETREUID */ } ACE_INLINE pid_t ACE_OS::setsid (void) { ACE_OS_TRACE ("ACE_OS::setsid"); #if defined (ACE_LACKS_SETSID) ACE_NOTSUP_RETURN (-1); #else ACE_OSCALL_RETURN (::setsid (), int, -1); # endif /* ACE_LACKS_SETSID */ } ACE_INLINE int ACE_OS::setuid (uid_t uid) { ACE_OS_TRACE ("ACE_OS::setuid"); #if defined (ACE_LACKS_SETUID) ACE_UNUSED_ARG (uid); ACE_NOTSUP_RETURN (-1); # else ACE_OSCALL_RETURN (::setuid (uid), int, -1); # endif /* ACE_LACKS_SETUID */ } ACE_INLINE int ACE_OS::seteuid (uid_t uid) { ACE_OS_TRACE ("ACE_OS::seteuid"); #if defined (ACE_LACKS_SETEUID) ACE_UNUSED_ARG (uid); ACE_NOTSUP_RETURN (-1); # else ACE_OSCALL_RETURN (::seteuid (uid), int, -1); # endif /* ACE_LACKS_SETEUID */ } ACE_INLINE int ACE_OS::sleep (u_int seconds) { ACE_OS_TRACE ("ACE_OS::sleep"); #if defined (ACE_WIN32) ::Sleep (seconds * ACE_ONE_SECOND_IN_MSECS); return 0; #elif defined (ACE_HAS_CLOCK_GETTIME) struct timespec rqtp; // Initializer doesn't work with Green Hills 1.8.7 rqtp.tv_sec = seconds; rqtp.tv_nsec = 0L; //FUZZ: disable check_for_lack_ACE_OS ACE_OSCALL_RETURN (::nanosleep (&rqtp, 0), int, -1); //FUZZ: enable check_for_lack_ACE_OS #else ACE_OSCALL_RETURN (::sleep (seconds), int, -1); #endif /* ACE_WIN32 */ } ACE_INLINE int ACE_OS::sleep (const ACE_Time_Value &tv) { ACE_OS_TRACE ("ACE_OS::sleep"); #if defined (ACE_WIN32) ::Sleep (tv.msec ()); return 0; #elif defined (ACE_HAS_CLOCK_GETTIME) timespec_t rqtp = tv; //FUZZ: disable check_for_lack_ACE_OS ACE_OSCALL_RETURN (::nanosleep (&rqtp, 0), int, -1); //FUZZ: enable check_for_lack_ACE_OS #else # if defined (ACE_HAS_NONCONST_SELECT_TIMEVAL) // Copy the timeval, because this platform doesn't declare the timeval // as a pointer to const. timeval tv_copy = tv; //FUZZ: disable check_for_lack_ACE_OS ACE_OSCALL_RETURN (::select (0, 0, 0, 0, &tv_copy), int, -1); //FUZZ: enable check_for_lack_ACE_OS # else /* ! ACE_HAS_NONCONST_SELECT_TIMEVAL */ const timeval *tvp = tv; //FUZZ: disable check_for_lack_ACE_OS ACE_OSCALL_RETURN (::select (0, 0, 0, 0, tvp), int, -1); //FUZZ: enable check_for_lack_ACE_OS # endif /* ACE_HAS_NONCONST_SELECT_TIMEVAL */ #endif /* ACE_WIN32 */ } ACE_INLINE void ACE_OS::swab (const void *src, void *dest, ssize_t length) { #if defined (ACE_LACKS_SWAB) // ------------------------------------------------------------ // The following copyright notice applies to the swab() // implementation within this "ACE_LACKS_SWAB" block of code. // ------------------------------------------------------------ /* Copyright (c) 1994-2006 Red Hat, Inc. All rights reserved. This copyrighted material is made available to anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the BSD License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. A copy of this license is available at http://www.opensource.org/licenses. Any Red Hat trademarks that are incorporated in the source code or documentation are not subject to the BSD License and may only be used or replicated with the express permission of Red Hat, Inc. */ const char *from = static_cast (src); char *to = static_cast (dest); ssize_t ptr = 0; for (ptr = 1; ptr < length; ptr += 2) { char p = from[ptr]; char q = from[ptr-1]; to[ptr-1] = p; to[ptr ] = q; } if (ptr == length) /* I.e., if length is odd, */ to[ptr-1] = 0; /* then pad with a NUL. */ #elif defined (ACE_HAS_NONCONST_SWAB) const char *tmp = static_cast (src); char *from = const_cast (tmp); char *to = static_cast (dest); # if defined (ACE_HAS_INT_SWAB) int ilength = ACE_Utils::truncate_cast (length); # if defined (ACE_SWAB_EQUIVALENT) ACE_SWAB_EQUIVALENT (from, to, ilength); # else ::swab (from, to, ilength); # endif # else ::swab (from, to, length); # endif /* ACE_HAS_INT_SWAB */ #elif defined (ACE_HAS_CONST_CHAR_SWAB) const char *from = static_cast (src); char *to = static_cast (dest); ::swab (from, to, length); #else ::swab (src, dest, length); #endif /* ACE_LACKS_SWAB */ } ACE_INLINE long ACE_OS::sysconf (int name) { ACE_OS_TRACE ("ACE_OS::sysconf"); #if defined (ACE_LACKS_SYSCONF) ACE_UNUSED_ARG (name); ACE_NOTSUP_RETURN (-1); #else ACE_OSCALL_RETURN (::sysconf (name), long, -1); #endif /* ACE_LACKS_SYSCONF */ } ACE_INLINE long ACE_OS::sysinfo (int cmd, char *buf, long count) { ACE_OS_TRACE ("ACE_OS::sysinfo"); #if defined (ACE_HAS_SYSV_SYSINFO) ACE_OSCALL_RETURN (::sysinfo (cmd, buf, count), long, -1); #else ACE_UNUSED_ARG (cmd); ACE_UNUSED_ARG (buf); ACE_UNUSED_ARG (count); ACE_NOTSUP_RETURN (0); #endif /* ACE_HAS_SYSV_SYSINFO */ } ACE_INLINE int ACE_OS::truncate (const ACE_TCHAR *filename, ACE_OFF_T offset) { ACE_OS_TRACE ("ACE_OS::truncate"); #if defined (ACE_WIN32) ACE_HANDLE handle = ACE_OS::open (filename, O_WRONLY, ACE_DEFAULT_FILE_PERMS); # if !defined (ACE_LACKS_WIN32_SETFILEPOINTEREX) LARGE_INTEGER loffset; loffset.QuadPart = offset; #else LONG low_offset = ACE_LOW_PART(offset); LONG high_offset = ACE_HIGH_PART(offset); #endif if (handle == ACE_INVALID_HANDLE) ACE_FAIL_RETURN (-1); # if !defined (ACE_LACKS_WIN32_SETFILEPOINTEREX) else if (::SetFilePointerEx (handle, loffset, 0, FILE_BEGIN)) # else else if (::SetFilePointer (handle, low_offset, &high_offset, FILE_BEGIN) != INVALID_SET_FILE_POINTER || GetLastError () == NO_ERROR) # endif /* ACE_LACKS_WIN32_SETFILEPOINTEREX */ { BOOL result = ::SetEndOfFile (handle); ::CloseHandle (handle); ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (result, ace_result_), int, -1); } else { ::CloseHandle (handle); ACE_FAIL_RETURN (-1); } /* NOTREACHED */ #elif !defined (ACE_LACKS_TRUNCATE) ACE_OSCALL_RETURN (::truncate (ACE_TEXT_ALWAYS_CHAR (filename), offset), int, -1); #else ACE_UNUSED_ARG (filename); ACE_UNUSED_ARG (offset); ACE_NOTSUP_RETURN (-1); #endif /* ACE_WIN32 */ } ACE_INLINE useconds_t ACE_OS::ualarm (useconds_t usecs, useconds_t interval) { ACE_OS_TRACE ("ACE_OS::ualarm"); #if defined (ACE_HAS_UALARM) return ::ualarm (usecs, interval); #elif !defined (ACE_LACKS_UNIX_SIGNALS) && !defined (ACE_LACKS_ALARM) ACE_UNUSED_ARG (interval); # if defined (ACE_VXWORKS) && ACE_VXWORKS >= 0x690 && defined (_WRS_CONFIG_LP64) return ::alarm (static_cast (usecs * ACE_ONE_SECOND_IN_USECS)); # else return ::alarm (usecs * ACE_ONE_SECOND_IN_USECS); #endif #else ACE_UNUSED_ARG (usecs); ACE_UNUSED_ARG (interval); ACE_NOTSUP_RETURN (0); #endif /* ACE_HAS_UALARM */ } ACE_INLINE useconds_t ACE_OS::ualarm (const ACE_Time_Value &tv, const ACE_Time_Value &tv_interval) { ACE_OS_TRACE ("ACE_OS::ualarm"); #if defined (ACE_HAS_UALARM) useconds_t usecs = (tv.sec () * ACE_ONE_SECOND_IN_USECS) + tv.usec (); useconds_t interval = (tv_interval.sec () * ACE_ONE_SECOND_IN_USECS) + tv_interval.usec (); return ::ualarm (usecs, interval); #elif !defined (ACE_LACKS_UNIX_SIGNALS) && !defined (ACE_LACKS_ALARM) ACE_UNUSED_ARG (tv_interval); # if defined (ACE_VXWORKS) && ACE_VXWORKS >= 0x690 && defined (_WRS_CONFIG_LP64) return ::alarm (static_cast (tv.sec ())); # else return ::alarm (tv.sec ()); # endif #else ACE_UNUSED_ARG (tv_interval); ACE_UNUSED_ARG (tv); ACE_NOTSUP_RETURN (0); #endif /* ACE_HAS_UALARM */ } ACE_INLINE int ACE_OS::unlink (const char *path) { ACE_OS_TRACE ("ACE_OS::unlink"); # if defined (ACE_HAS_NONCONST_UNLINK) ACE_OSCALL_RETURN (::unlink (const_cast (path)), int, -1); # elif defined (ACE_HAS_WINCE) // @@ The problem is, DeleteFile is not actually equals to unlink. ;( ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::DeleteFile (ACE_TEXT_CHAR_TO_TCHAR (path)), ace_result_), int, -1); # elif defined (ACE_LACKS_UNLINK) ACE_UNUSED_ARG (path); ACE_NOTSUP_RETURN (-1); # elif defined (ACE_UNLINK_EQUIVALENT) ACE_OSCALL_RETURN (ACE_UNLINK_EQUIVALENT (path), int, -1); # else ACE_OSCALL_RETURN (::unlink (path), int, -1); # endif /* ACE_HAS_NONCONST_UNLINK */ } #if defined (ACE_HAS_WCHAR) ACE_INLINE int ACE_OS::unlink (const wchar_t *path) { ACE_OS_TRACE ("ACE_OS::unlink"); # if defined (ACE_HAS_WINCE) // @@ The problem is, DeleteFile is not actually equals to unlink. ;( ACE_WIN32CALL_RETURN (ACE_ADAPT_RETVAL (::DeleteFileW (path), ace_result_), int, -1); # elif defined (ACE_WIN32) ACE_OSCALL_RETURN (::_wunlink (path), int, -1); # else ACE_Wide_To_Ascii npath (path); return ACE_OS::unlink (npath.char_rep ()); # endif /* ACE_HAS_WINCE */ } #endif /* ACE_HAS_WCHAR */ ACE_INLINE ssize_t ACE_OS::write (ACE_HANDLE handle, const void *buf, size_t nbyte) { ACE_OS_TRACE ("ACE_OS::write"); #if defined (ACE_WIN32) DWORD bytes_written; // This is set to 0 byte WriteFile. // Strictly correctly, we should loop writing all the data if more // than a DWORD length can hold. DWORD short_nbyte = static_cast (nbyte); if (::WriteFile (handle, buf, short_nbyte, &bytes_written, 0)) return (ssize_t) bytes_written; else ACE_FAIL_RETURN (-1); #else # if defined (ACE_HAS_CHARPTR_SOCKOPT) ACE_OSCALL_RETURN (::write (handle, static_cast (const_cast (buf)), nbyte), ssize_t, -1); # else ACE_OSCALL_RETURN (::write (handle, buf, nbyte), ssize_t, -1); # endif /* ACE_HAS_CHARPTR_SOCKOPT */ #endif /* ACE_WIN32 */ } ACE_INLINE ssize_t ACE_OS::write (ACE_HANDLE handle, const void *buf, size_t nbyte, ACE_OVERLAPPED *overlapped) { ACE_OS_TRACE ("ACE_OS::write"); #if defined (ACE_WIN32) DWORD bytes_written; // This is set to 0 byte WriteFile. DWORD short_nbyte = static_cast (nbyte); if (::WriteFile (handle, buf, short_nbyte, &bytes_written, overlapped)) return (ssize_t) bytes_written; else ACE_FAIL_RETURN (-1); #else ACE_UNUSED_ARG (overlapped); return ACE_OS::write (handle, buf, nbyte); #endif /* ACE_WIN32 */ } ACE_END_VERSIONED_NAMESPACE_DECL