Mercurial > hg > graal-compiler
comparison src/os/windows/vm/os_windows.cpp @ 2023:54f5dd2aa1d9
Merge
author | zgu |
---|---|
date | Sat, 11 Dec 2010 13:46:36 -0500 |
parents | 2d4762ec74af cb2d0a362639 |
children | aa6e219afbf1 1e637defdda6 |
comparison
equal
deleted
inserted
replaced
2022:2d4762ec74af | 2023:54f5dd2aa1d9 |
---|---|
45 #include "prims/jvm.h" | 45 #include "prims/jvm.h" |
46 #include "prims/jvm_misc.hpp" | 46 #include "prims/jvm_misc.hpp" |
47 #include "runtime/arguments.hpp" | 47 #include "runtime/arguments.hpp" |
48 #include "runtime/extendedPC.hpp" | 48 #include "runtime/extendedPC.hpp" |
49 #include "runtime/globals.hpp" | 49 #include "runtime/globals.hpp" |
50 #include "runtime/hpi.hpp" | |
51 #include "runtime/interfaceSupport.hpp" | 50 #include "runtime/interfaceSupport.hpp" |
52 #include "runtime/java.hpp" | 51 #include "runtime/java.hpp" |
53 #include "runtime/javaCalls.hpp" | 52 #include "runtime/javaCalls.hpp" |
54 #include "runtime/mutexLocker.hpp" | 53 #include "runtime/mutexLocker.hpp" |
55 #include "runtime/objectMonitor.hpp" | 54 #include "runtime/objectMonitor.hpp" |
1043 free(dirp->path); | 1042 free(dirp->path); |
1044 free(dirp); | 1043 free(dirp); |
1045 return 0; | 1044 return 0; |
1046 } | 1045 } |
1047 | 1046 |
1048 const char* os::dll_file_extension() { return ".dll"; } | |
1049 | |
1050 const char* os::get_temp_directory() { | 1047 const char* os::get_temp_directory() { |
1051 const char *prop = Arguments::get_property("java.io.tmpdir"); | 1048 const char *prop = Arguments::get_property("java.io.tmpdir"); |
1052 if (prop != 0) return prop; | 1049 if (prop != 0) return prop; |
1053 static char path_buf[MAX_PATH]; | 1050 static char path_buf[MAX_PATH]; |
1054 if (GetTempPath(MAX_PATH, path_buf)>0) | 1051 if (GetTempPath(MAX_PATH, path_buf)>0) |
1066 return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES; | 1063 return GetFileAttributes(filename) != INVALID_FILE_ATTRIBUTES; |
1067 } | 1064 } |
1068 | 1065 |
1069 void os::dll_build_name(char *buffer, size_t buflen, | 1066 void os::dll_build_name(char *buffer, size_t buflen, |
1070 const char* pname, const char* fname) { | 1067 const char* pname, const char* fname) { |
1071 // Copied from libhpi | |
1072 const size_t pnamelen = pname ? strlen(pname) : 0; | 1068 const size_t pnamelen = pname ? strlen(pname) : 0; |
1073 const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0; | 1069 const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0; |
1074 | 1070 |
1075 // Quietly truncates on buffer overflow. Should be an error. | 1071 // Quietly truncates on buffer overflow. Should be an error. |
1076 if (pnamelen + strlen(fname) + 10 > buflen) { | 1072 if (pnamelen + strlen(fname) + 10 > buflen) { |
1374 return true; | 1370 return true; |
1375 } | 1371 } |
1376 if (offset != NULL) *offset = -1; | 1372 if (offset != NULL) *offset = -1; |
1377 if (buf != NULL) buf[0] = '\0'; | 1373 if (buf != NULL) buf[0] = '\0'; |
1378 return false; | 1374 return false; |
1379 } | |
1380 | |
1381 void* os::dll_lookup(void* handle, const char* name) { | |
1382 return GetProcAddress((HMODULE)handle, name); | |
1383 } | 1375 } |
1384 | 1376 |
1385 // save the start and end address of jvm.dll into param[0] and param[1] | 1377 // save the start and end address of jvm.dll into param[0] and param[1] |
1386 static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr, | 1378 static int _locate_jvm_dll(int pid, char* mod_fname, address base_addr, |
1387 unsigned size, void * param) { | 1379 unsigned size, void * param) { |
1714 if (saved_jvm_path[0] != 0) { | 1706 if (saved_jvm_path[0] != 0) { |
1715 strcpy(buf, saved_jvm_path); | 1707 strcpy(buf, saved_jvm_path); |
1716 return; | 1708 return; |
1717 } | 1709 } |
1718 | 1710 |
1711 buf[0] = '\0'; | |
1712 if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) { | |
1713 // Support for the gamma launcher. Check for an | |
1714 // ALT_JAVA_HOME or JAVA_HOME environment variable | |
1715 // and fix up the path so it looks like | |
1716 // libjvm.so is installed there (append a fake suffix | |
1717 // hotspot/libjvm.so). | |
1718 char* java_home_var = ::getenv("ALT_JAVA_HOME"); | |
1719 if (java_home_var == NULL) { | |
1720 java_home_var = ::getenv("JAVA_HOME"); | |
1721 } | |
1722 if (java_home_var != NULL && java_home_var[0] != 0) { | |
1723 | |
1724 strncpy(buf, java_home_var, buflen); | |
1725 | |
1726 // determine if this is a legacy image or modules image | |
1727 // modules image doesn't have "jre" subdirectory | |
1728 size_t len = strlen(buf); | |
1729 char* jrebin_p = buf + len; | |
1730 jio_snprintf(jrebin_p, buflen-len, "\\jre\\bin\\"); | |
1731 if (0 != _access(buf, 0)) { | |
1732 jio_snprintf(jrebin_p, buflen-len, "\\bin\\"); | |
1733 } | |
1734 len = strlen(buf); | |
1735 jio_snprintf(buf + len, buflen-len, "hotspot\\jvm.dll"); | |
1736 } | |
1737 } | |
1738 | |
1739 if(buf[0] == '\0') { | |
1719 GetModuleFileName(vm_lib_handle, buf, buflen); | 1740 GetModuleFileName(vm_lib_handle, buf, buflen); |
1741 } | |
1720 strcpy(saved_jvm_path, buf); | 1742 strcpy(saved_jvm_path, buf); |
1721 } | 1743 } |
1722 | 1744 |
1723 | 1745 |
1724 void os::print_jni_name_prefix_on(outputStream* st, int args_size) { | 1746 void os::print_jni_name_prefix_on(outputStream* st, int args_size) { |
1730 | 1752 |
1731 void os::print_jni_name_suffix_on(outputStream* st, int args_size) { | 1753 void os::print_jni_name_suffix_on(outputStream* st, int args_size) { |
1732 #ifndef _WIN64 | 1754 #ifndef _WIN64 |
1733 st->print("@%d", args_size * sizeof(int)); | 1755 st->print("@%d", args_size * sizeof(int)); |
1734 #endif | 1756 #endif |
1757 } | |
1758 | |
1759 // This method is a copy of JDK's sysGetLastErrorString | |
1760 // from src/windows/hpi/src/system_md.c | |
1761 | |
1762 size_t os::lasterror(char *buf, size_t len) { | |
1763 long errval; | |
1764 | |
1765 if ((errval = GetLastError()) != 0) { | |
1766 /* DOS error */ | |
1767 int n = (int)FormatMessage( | |
1768 FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, | |
1769 NULL, | |
1770 errval, | |
1771 0, | |
1772 buf, | |
1773 (DWORD)len, | |
1774 NULL); | |
1775 if (n > 3) { | |
1776 /* Drop final '.', CR, LF */ | |
1777 if (buf[n - 1] == '\n') n--; | |
1778 if (buf[n - 1] == '\r') n--; | |
1779 if (buf[n - 1] == '.') n--; | |
1780 buf[n] = '\0'; | |
1781 } | |
1782 return n; | |
1783 } | |
1784 | |
1785 if (errno != 0) { | |
1786 /* C runtime error that has no corresponding DOS error code */ | |
1787 const char *s = strerror(errno); | |
1788 size_t n = strlen(s); | |
1789 if (n >= len) n = len - 1; | |
1790 strncpy(buf, s, n); | |
1791 buf[n] = '\0'; | |
1792 return n; | |
1793 } | |
1794 return 0; | |
1735 } | 1795 } |
1736 | 1796 |
1737 // sun.misc.Signal | 1797 // sun.misc.Signal |
1738 // NOTE that this is a workaround for an apparent kernel bug where if | 1798 // NOTE that this is a workaround for an apparent kernel bug where if |
1739 // a signal handler for SIGBREAK is installed then that signal handler | 1799 // a signal handler for SIGBREAK is installed then that signal handler |
2939 // 1: Thread is running now | 2999 // 1: Thread is running now |
2940 // >1: Thread is still suspended. | 3000 // >1: Thread is still suspended. |
2941 assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back | 3001 assert(ret != SYS_THREAD_ERROR, "StartThread failed"); // should propagate back |
2942 } | 3002 } |
2943 | 3003 |
2944 size_t os::read(int fd, void *buf, unsigned int nBytes) { | |
2945 return ::read(fd, buf, nBytes); | |
2946 } | |
2947 | |
2948 class HighResolutionInterval { | 3004 class HighResolutionInterval { |
2949 // The default timer resolution seems to be 10 milliseconds. | 3005 // The default timer resolution seems to be 10 milliseconds. |
2950 // (Where is this written down?) | 3006 // (Where is this written down?) |
2951 // If someone wants to sleep for only a fraction of the default, | 3007 // If someone wants to sleep for only a fraction of the default, |
2952 // then we set the timer resolution down to 1 millisecond for | 3008 // then we set the timer resolution down to 1 millisecond for |
3421 fp_control_word |= invalid; | 3477 fp_control_word |= invalid; |
3422 __asm { fldcw fp_control_word } | 3478 __asm { fldcw fp_control_word } |
3423 #endif | 3479 #endif |
3424 } | 3480 } |
3425 | 3481 |
3426 // Initialize HPI. | |
3427 jint hpi_result = hpi::initialize(); | |
3428 if (hpi_result != JNI_OK) { return hpi_result; } | |
3429 | |
3430 // If stack_commit_size is 0, windows will reserve the default size, | 3482 // If stack_commit_size is 0, windows will reserve the default size, |
3431 // but only commit a small portion of it. | 3483 // but only commit a small portion of it. |
3432 size_t stack_commit_size = round_to(ThreadStackSize*K, os::vm_page_size()); | 3484 size_t stack_commit_size = round_to(ThreadStackSize*K, os::vm_page_size()); |
3433 size_t default_reserve_size = os::win32::default_stack_size(); | 3485 size_t default_reserve_size = os::win32::default_stack_size(); |
3434 size_t actual_reserve_size = stack_commit_size; | 3486 size_t actual_reserve_size = stack_commit_size; |
3529 char pathbuf[MAX_PATH]; | 3581 char pathbuf[MAX_PATH]; |
3530 if (strlen(path) > MAX_PATH - 1) { | 3582 if (strlen(path) > MAX_PATH - 1) { |
3531 errno = ENAMETOOLONG; | 3583 errno = ENAMETOOLONG; |
3532 return -1; | 3584 return -1; |
3533 } | 3585 } |
3534 hpi::native_path(strcpy(pathbuf, path)); | 3586 os::native_path(strcpy(pathbuf, path)); |
3535 int ret = ::stat(pathbuf, sbuf); | 3587 int ret = ::stat(pathbuf, sbuf); |
3536 if (sbuf != NULL && UseUTCFileTimestamp) { | 3588 if (sbuf != NULL && UseUTCFileTimestamp) { |
3537 // Fix for 6539723. st_mtime returned from stat() is dependent on | 3589 // Fix for 6539723. st_mtime returned from stat() is dependent on |
3538 // the system timezone and so can return different values for the | 3590 // the system timezone and so can return different values for the |
3539 // same file if/when daylight savings time changes. This adjustment | 3591 // same file if/when daylight savings time changes. This adjustment |
3673 // DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield() | 3725 // DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield() |
3674 bool os::dont_yield() { | 3726 bool os::dont_yield() { |
3675 return DontYieldALot; | 3727 return DontYieldALot; |
3676 } | 3728 } |
3677 | 3729 |
3730 // This method is a slightly reworked copy of JDK's sysOpen | |
3731 // from src/windows/hpi/src/sys_api_md.c | |
3732 | |
3733 int os::open(const char *path, int oflag, int mode) { | |
3734 char pathbuf[MAX_PATH]; | |
3735 | |
3736 if (strlen(path) > MAX_PATH - 1) { | |
3737 errno = ENAMETOOLONG; | |
3738 return -1; | |
3739 } | |
3740 os::native_path(strcpy(pathbuf, path)); | |
3741 return ::open(pathbuf, oflag | O_BINARY | O_NOINHERIT, mode); | |
3742 } | |
3743 | |
3678 // Is a (classpath) directory empty? | 3744 // Is a (classpath) directory empty? |
3679 bool os::dir_is_empty(const char* path) { | 3745 bool os::dir_is_empty(const char* path) { |
3680 WIN32_FIND_DATA fd; | 3746 WIN32_FIND_DATA fd; |
3681 HANDLE f = FindFirstFile(path, &fd); | 3747 HANDLE f = FindFirstFile(path, &fd); |
3682 if (f == INVALID_HANDLE_VALUE) { | 3748 if (f == INVALID_HANDLE_VALUE) { |
3703 // move file pointer to the specified offset | 3769 // move file pointer to the specified offset |
3704 jlong os::seek_to_file_offset(int fd, jlong offset) { | 3770 jlong os::seek_to_file_offset(int fd, jlong offset) { |
3705 return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET); | 3771 return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET); |
3706 } | 3772 } |
3707 | 3773 |
3774 | |
3775 jlong os::lseek(int fd, jlong offset, int whence) { | |
3776 return (jlong) ::_lseeki64(fd, offset, whence); | |
3777 } | |
3778 | |
3779 // This method is a slightly reworked copy of JDK's sysNativePath | |
3780 // from src/windows/hpi/src/path_md.c | |
3781 | |
3782 /* Convert a pathname to native format. On win32, this involves forcing all | |
3783 separators to be '\\' rather than '/' (both are legal inputs, but Win95 | |
3784 sometimes rejects '/') and removing redundant separators. The input path is | |
3785 assumed to have been converted into the character encoding used by the local | |
3786 system. Because this might be a double-byte encoding, care is taken to | |
3787 treat double-byte lead characters correctly. | |
3788 | |
3789 This procedure modifies the given path in place, as the result is never | |
3790 longer than the original. There is no error return; this operation always | |
3791 succeeds. */ | |
3792 char * os::native_path(char *path) { | |
3793 char *src = path, *dst = path, *end = path; | |
3794 char *colon = NULL; /* If a drive specifier is found, this will | |
3795 point to the colon following the drive | |
3796 letter */ | |
3797 | |
3798 /* Assumption: '/', '\\', ':', and drive letters are never lead bytes */ | |
3799 assert(((!::IsDBCSLeadByte('/')) | |
3800 && (!::IsDBCSLeadByte('\\')) | |
3801 && (!::IsDBCSLeadByte(':'))), | |
3802 "Illegal lead byte"); | |
3803 | |
3804 /* Check for leading separators */ | |
3805 #define isfilesep(c) ((c) == '/' || (c) == '\\') | |
3806 while (isfilesep(*src)) { | |
3807 src++; | |
3808 } | |
3809 | |
3810 if (::isalpha(*src) && !::IsDBCSLeadByte(*src) && src[1] == ':') { | |
3811 /* Remove leading separators if followed by drive specifier. This | |
3812 hack is necessary to support file URLs containing drive | |
3813 specifiers (e.g., "file://c:/path"). As a side effect, | |
3814 "/c:/path" can be used as an alternative to "c:/path". */ | |
3815 *dst++ = *src++; | |
3816 colon = dst; | |
3817 *dst++ = ':'; | |
3818 src++; | |
3819 } else { | |
3820 src = path; | |
3821 if (isfilesep(src[0]) && isfilesep(src[1])) { | |
3822 /* UNC pathname: Retain first separator; leave src pointed at | |
3823 second separator so that further separators will be collapsed | |
3824 into the second separator. The result will be a pathname | |
3825 beginning with "\\\\" followed (most likely) by a host name. */ | |
3826 src = dst = path + 1; | |
3827 path[0] = '\\'; /* Force first separator to '\\' */ | |
3828 } | |
3829 } | |
3830 | |
3831 end = dst; | |
3832 | |
3833 /* Remove redundant separators from remainder of path, forcing all | |
3834 separators to be '\\' rather than '/'. Also, single byte space | |
3835 characters are removed from the end of the path because those | |
3836 are not legal ending characters on this operating system. | |
3837 */ | |
3838 while (*src != '\0') { | |
3839 if (isfilesep(*src)) { | |
3840 *dst++ = '\\'; src++; | |
3841 while (isfilesep(*src)) src++; | |
3842 if (*src == '\0') { | |
3843 /* Check for trailing separator */ | |
3844 end = dst; | |
3845 if (colon == dst - 2) break; /* "z:\\" */ | |
3846 if (dst == path + 1) break; /* "\\" */ | |
3847 if (dst == path + 2 && isfilesep(path[0])) { | |
3848 /* "\\\\" is not collapsed to "\\" because "\\\\" marks the | |
3849 beginning of a UNC pathname. Even though it is not, by | |
3850 itself, a valid UNC pathname, we leave it as is in order | |
3851 to be consistent with the path canonicalizer as well | |
3852 as the win32 APIs, which treat this case as an invalid | |
3853 UNC pathname rather than as an alias for the root | |
3854 directory of the current drive. */ | |
3855 break; | |
3856 } | |
3857 end = --dst; /* Path does not denote a root directory, so | |
3858 remove trailing separator */ | |
3859 break; | |
3860 } | |
3861 end = dst; | |
3862 } else { | |
3863 if (::IsDBCSLeadByte(*src)) { /* Copy a double-byte character */ | |
3864 *dst++ = *src++; | |
3865 if (*src) *dst++ = *src++; | |
3866 end = dst; | |
3867 } else { /* Copy a single-byte character */ | |
3868 char c = *src++; | |
3869 *dst++ = c; | |
3870 /* Space is not a legal ending character */ | |
3871 if (c != ' ') end = dst; | |
3872 } | |
3873 } | |
3874 } | |
3875 | |
3876 *end = '\0'; | |
3877 | |
3878 /* For "z:", add "." to work around a bug in the C runtime library */ | |
3879 if (colon == dst - 1) { | |
3880 path[2] = '.'; | |
3881 path[3] = '\0'; | |
3882 } | |
3883 | |
3884 #ifdef DEBUG | |
3885 jio_fprintf(stderr, "sysNativePath: %s\n", path); | |
3886 #endif DEBUG | |
3887 return path; | |
3888 } | |
3889 | |
3890 // This code is a copy of JDK's sysSetLength | |
3891 // from src/windows/hpi/src/sys_api_md.c | |
3892 | |
3893 int os::ftruncate(int fd, jlong length) { | |
3894 HANDLE h = (HANDLE)::_get_osfhandle(fd); | |
3895 long high = (long)(length >> 32); | |
3896 DWORD ret; | |
3897 | |
3898 if (h == (HANDLE)(-1)) { | |
3899 return -1; | |
3900 } | |
3901 | |
3902 ret = ::SetFilePointer(h, (long)(length), &high, FILE_BEGIN); | |
3903 if ((ret == 0xFFFFFFFF) && (::GetLastError() != NO_ERROR)) { | |
3904 return -1; | |
3905 } | |
3906 | |
3907 if (::SetEndOfFile(h) == FALSE) { | |
3908 return -1; | |
3909 } | |
3910 | |
3911 return 0; | |
3912 } | |
3913 | |
3914 | |
3915 // This code is a copy of JDK's sysSync | |
3916 // from src/windows/hpi/src/sys_api_md.c | |
3917 // except for the legacy workaround for a bug in Win 98 | |
3918 | |
3919 int os::fsync(int fd) { | |
3920 HANDLE handle = (HANDLE)::_get_osfhandle(fd); | |
3921 | |
3922 if ( (!::FlushFileBuffers(handle)) && | |
3923 (GetLastError() != ERROR_ACCESS_DENIED) ) { | |
3924 /* from winerror.h */ | |
3925 return -1; | |
3926 } | |
3927 return 0; | |
3928 } | |
3929 | |
3930 static int nonSeekAvailable(int, long *); | |
3931 static int stdinAvailable(int, long *); | |
3932 | |
3933 #define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR) | |
3934 #define S_ISFIFO(mode) (((mode) & _S_IFIFO) == _S_IFIFO) | |
3935 | |
3936 // This code is a copy of JDK's sysAvailable | |
3937 // from src/windows/hpi/src/sys_api_md.c | |
3938 | |
3939 int os::available(int fd, jlong *bytes) { | |
3940 jlong cur, end; | |
3941 struct _stati64 stbuf64; | |
3942 | |
3943 if (::_fstati64(fd, &stbuf64) >= 0) { | |
3944 int mode = stbuf64.st_mode; | |
3945 if (S_ISCHR(mode) || S_ISFIFO(mode)) { | |
3946 int ret; | |
3947 long lpbytes; | |
3948 if (fd == 0) { | |
3949 ret = stdinAvailable(fd, &lpbytes); | |
3950 } else { | |
3951 ret = nonSeekAvailable(fd, &lpbytes); | |
3952 } | |
3953 (*bytes) = (jlong)(lpbytes); | |
3954 return ret; | |
3955 } | |
3956 if ((cur = ::_lseeki64(fd, 0L, SEEK_CUR)) == -1) { | |
3957 return FALSE; | |
3958 } else if ((end = ::_lseeki64(fd, 0L, SEEK_END)) == -1) { | |
3959 return FALSE; | |
3960 } else if (::_lseeki64(fd, cur, SEEK_SET) == -1) { | |
3961 return FALSE; | |
3962 } | |
3963 *bytes = end - cur; | |
3964 return TRUE; | |
3965 } else { | |
3966 return FALSE; | |
3967 } | |
3968 } | |
3969 | |
3970 // This code is a copy of JDK's nonSeekAvailable | |
3971 // from src/windows/hpi/src/sys_api_md.c | |
3972 | |
3973 static int nonSeekAvailable(int fd, long *pbytes) { | |
3974 /* This is used for available on non-seekable devices | |
3975 * (like both named and anonymous pipes, such as pipes | |
3976 * connected to an exec'd process). | |
3977 * Standard Input is a special case. | |
3978 * | |
3979 */ | |
3980 HANDLE han; | |
3981 | |
3982 if ((han = (HANDLE) ::_get_osfhandle(fd)) == (HANDLE)(-1)) { | |
3983 return FALSE; | |
3984 } | |
3985 | |
3986 if (! ::PeekNamedPipe(han, NULL, 0, NULL, (LPDWORD)pbytes, NULL)) { | |
3987 /* PeekNamedPipe fails when at EOF. In that case we | |
3988 * simply make *pbytes = 0 which is consistent with the | |
3989 * behavior we get on Solaris when an fd is at EOF. | |
3990 * The only alternative is to raise an Exception, | |
3991 * which isn't really warranted. | |
3992 */ | |
3993 if (::GetLastError() != ERROR_BROKEN_PIPE) { | |
3994 return FALSE; | |
3995 } | |
3996 *pbytes = 0; | |
3997 } | |
3998 return TRUE; | |
3999 } | |
4000 | |
4001 #define MAX_INPUT_EVENTS 2000 | |
4002 | |
4003 // This code is a copy of JDK's stdinAvailable | |
4004 // from src/windows/hpi/src/sys_api_md.c | |
4005 | |
4006 static int stdinAvailable(int fd, long *pbytes) { | |
4007 HANDLE han; | |
4008 DWORD numEventsRead = 0; /* Number of events read from buffer */ | |
4009 DWORD numEvents = 0; /* Number of events in buffer */ | |
4010 DWORD i = 0; /* Loop index */ | |
4011 DWORD curLength = 0; /* Position marker */ | |
4012 DWORD actualLength = 0; /* Number of bytes readable */ | |
4013 BOOL error = FALSE; /* Error holder */ | |
4014 INPUT_RECORD *lpBuffer; /* Pointer to records of input events */ | |
4015 | |
4016 if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) { | |
4017 return FALSE; | |
4018 } | |
4019 | |
4020 /* Construct an array of input records in the console buffer */ | |
4021 error = ::GetNumberOfConsoleInputEvents(han, &numEvents); | |
4022 if (error == 0) { | |
4023 return nonSeekAvailable(fd, pbytes); | |
4024 } | |
4025 | |
4026 /* lpBuffer must fit into 64K or else PeekConsoleInput fails */ | |
4027 if (numEvents > MAX_INPUT_EVENTS) { | |
4028 numEvents = MAX_INPUT_EVENTS; | |
4029 } | |
4030 | |
4031 lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD)); | |
4032 if (lpBuffer == NULL) { | |
4033 return FALSE; | |
4034 } | |
4035 | |
4036 error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead); | |
4037 if (error == 0) { | |
4038 os::free(lpBuffer); | |
4039 return FALSE; | |
4040 } | |
4041 | |
4042 /* Examine input records for the number of bytes available */ | |
4043 for(i=0; i<numEvents; i++) { | |
4044 if (lpBuffer[i].EventType == KEY_EVENT) { | |
4045 | |
4046 KEY_EVENT_RECORD *keyRecord = (KEY_EVENT_RECORD *) | |
4047 &(lpBuffer[i].Event); | |
4048 if (keyRecord->bKeyDown == TRUE) { | |
4049 CHAR *keyPressed = (CHAR *) &(keyRecord->uChar); | |
4050 curLength++; | |
4051 if (*keyPressed == '\r') { | |
4052 actualLength = curLength; | |
4053 } | |
4054 } | |
4055 } | |
4056 } | |
4057 | |
4058 if(lpBuffer != NULL) { | |
4059 os::free(lpBuffer); | |
4060 } | |
4061 | |
4062 *pbytes = (long) actualLength; | |
4063 return TRUE; | |
4064 } | |
3708 | 4065 |
3709 // Map a block of memory. | 4066 // Map a block of memory. |
3710 char* os::map_memory(int fd, const char* file_name, size_t file_offset, | 4067 char* os::map_memory(int fd, const char* file_name, size_t file_offset, |
3711 char *addr, size_t bytes, bool read_only, | 4068 char *addr, size_t bytes, bool read_only, |
3712 bool allow_exec) { | 4069 bool allow_exec) { |
3869 } | 4226 } |
3870 | 4227 |
3871 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); | 4228 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
3872 if (fd != -1) { | 4229 if (fd != -1) { |
3873 struct stat buf; | 4230 struct stat buf; |
3874 close(fd); | 4231 ::close(fd); |
3875 while (::stat(filename, &buf) == 0) { | 4232 while (::stat(filename, &buf) == 0) { |
3876 Sleep(100); | 4233 Sleep(100); |
3877 } | 4234 } |
3878 } else { | 4235 } else { |
3879 jio_fprintf(stderr, | 4236 jio_fprintf(stderr, |
4230 | 4587 |
4231 | 4588 |
4232 // We don't build a headless jre for Windows | 4589 // We don't build a headless jre for Windows |
4233 bool os::is_headless_jre() { return false; } | 4590 bool os::is_headless_jre() { return false; } |
4234 | 4591 |
4592 // OS_SocketInterface | |
4593 // Not used on Windows | |
4594 | |
4595 // OS_SocketInterface | |
4596 typedef struct hostent * (PASCAL FAR *ws2_ifn_ptr_t)(...); | |
4597 ws2_ifn_ptr_t *get_host_by_name_fn = NULL; | |
4598 | |
4599 typedef CRITICAL_SECTION mutex_t; | |
4600 #define mutexInit(m) InitializeCriticalSection(m) | |
4601 #define mutexDestroy(m) DeleteCriticalSection(m) | |
4602 #define mutexLock(m) EnterCriticalSection(m) | |
4603 #define mutexUnlock(m) LeaveCriticalSection(m) | |
4604 | |
4605 static bool sockfnptrs_initialized = FALSE; | |
4606 static mutex_t sockFnTableMutex; | |
4607 | |
4608 /* is Winsock2 loaded? better to be explicit than to rely on sockfnptrs */ | |
4609 static bool winsock2Available = FALSE; | |
4610 | |
4611 | |
4612 static void initSockFnTable() { | |
4613 int (PASCAL FAR* WSAStartupPtr)(WORD, LPWSADATA); | |
4614 WSADATA wsadata; | |
4615 | |
4616 ::mutexInit(&sockFnTableMutex); | |
4617 ::mutexLock(&sockFnTableMutex); | |
4618 | |
4619 if (sockfnptrs_initialized == FALSE) { | |
4620 HMODULE hWinsock; | |
4621 | |
4622 /* try to load Winsock2, and if that fails, load Winsock */ | |
4623 hWinsock = ::LoadLibrary("ws2_32.dll"); | |
4624 | |
4625 if (hWinsock == NULL) { | |
4626 jio_fprintf(stderr, "Could not load Winsock 2 (error: %d)\n", | |
4627 ::GetLastError()); | |
4628 return; | |
4629 } | |
4630 | |
4631 /* If we loaded a DLL, then we might as well initialize it. */ | |
4632 WSAStartupPtr = (int (PASCAL FAR *)(WORD, LPWSADATA)) | |
4633 ::GetProcAddress(hWinsock, "WSAStartup"); | |
4634 | |
4635 if (WSAStartupPtr(MAKEWORD(1,1), &wsadata) != 0) { | |
4636 jio_fprintf(stderr, "Could not initialize Winsock\n"); | |
4637 } | |
4638 | |
4639 get_host_by_name_fn | |
4640 = (ws2_ifn_ptr_t*) GetProcAddress(hWinsock, "gethostbyname"); | |
4641 } | |
4642 | |
4643 assert(get_host_by_name_fn != NULL, | |
4644 "gethostbyname function not found"); | |
4645 sockfnptrs_initialized = TRUE; | |
4646 ::mutexUnlock(&sockFnTableMutex); | |
4647 } | |
4648 | |
4649 struct hostent* os::get_host_by_name(char* name) { | |
4650 if (!sockfnptrs_initialized) { | |
4651 initSockFnTable(); | |
4652 } | |
4653 | |
4654 assert(sockfnptrs_initialized == TRUE && get_host_by_name_fn != NULL, | |
4655 "sockfnptrs is not initialized or pointer to gethostbyname function is NULL"); | |
4656 return (*get_host_by_name_fn)(name); | |
4657 } | |
4658 | |
4659 | |
4660 int os::socket_close(int fd) { | |
4661 ShouldNotReachHere(); | |
4662 return 0; | |
4663 } | |
4664 | |
4665 int os::socket_available(int fd, jint *pbytes) { | |
4666 ShouldNotReachHere(); | |
4667 return 0; | |
4668 } | |
4669 | |
4670 int os::socket(int domain, int type, int protocol) { | |
4671 ShouldNotReachHere(); | |
4672 return 0; | |
4673 } | |
4674 | |
4675 int os::listen(int fd, int count) { | |
4676 ShouldNotReachHere(); | |
4677 return 0; | |
4678 } | |
4679 | |
4680 int os::connect(int fd, struct sockaddr *him, int len) { | |
4681 ShouldNotReachHere(); | |
4682 return 0; | |
4683 } | |
4684 | |
4685 int os::accept(int fd, struct sockaddr *him, int *len) { | |
4686 ShouldNotReachHere(); | |
4687 return 0; | |
4688 } | |
4689 | |
4690 int os::sendto(int fd, char *buf, int len, int flags, | |
4691 struct sockaddr *to, int tolen) { | |
4692 ShouldNotReachHere(); | |
4693 return 0; | |
4694 } | |
4695 | |
4696 int os::recvfrom(int fd, char *buf, int nBytes, int flags, | |
4697 sockaddr *from, int *fromlen) { | |
4698 ShouldNotReachHere(); | |
4699 return 0; | |
4700 } | |
4701 | |
4702 int os::recv(int fd, char *buf, int nBytes, int flags) { | |
4703 ShouldNotReachHere(); | |
4704 return 0; | |
4705 } | |
4706 | |
4707 int os::send(int fd, char *buf, int nBytes, int flags) { | |
4708 ShouldNotReachHere(); | |
4709 return 0; | |
4710 } | |
4711 | |
4712 int os::raw_send(int fd, char *buf, int nBytes, int flags) { | |
4713 ShouldNotReachHere(); | |
4714 return 0; | |
4715 } | |
4716 | |
4717 int os::timeout(int fd, long timeout) { | |
4718 ShouldNotReachHere(); | |
4719 return 0; | |
4720 } | |
4721 | |
4722 int os::get_host_name(char* name, int namelen) { | |
4723 ShouldNotReachHere(); | |
4724 return 0; | |
4725 } | |
4726 | |
4727 int os::socket_shutdown(int fd, int howto) { | |
4728 ShouldNotReachHere(); | |
4729 return 0; | |
4730 } | |
4731 | |
4732 int os::bind(int fd, struct sockaddr *him, int len) { | |
4733 ShouldNotReachHere(); | |
4734 return 0; | |
4735 } | |
4736 | |
4737 int os::get_sock_name(int fd, struct sockaddr *him, int *len) { | |
4738 ShouldNotReachHere(); | |
4739 return 0; | |
4740 } | |
4741 | |
4742 int os::get_sock_opt(int fd, int level, int optname, | |
4743 char *optval, int* optlen) { | |
4744 ShouldNotReachHere(); | |
4745 return 0; | |
4746 } | |
4747 | |
4748 int os::set_sock_opt(int fd, int level, int optname, | |
4749 const char *optval, int optlen) { | |
4750 ShouldNotReachHere(); | |
4751 return 0; | |
4752 } |