3703 // move file pointer to the specified offset |
3739 // move file pointer to the specified offset |
3704 jlong os::seek_to_file_offset(int fd, jlong offset) { |
3740 jlong os::seek_to_file_offset(int fd, jlong offset) { |
3705 return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET); |
3741 return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET); |
3706 } |
3742 } |
3707 |
3743 |
|
3744 |
|
3745 jlong os::lseek(int fd, jlong offset, int whence) { |
|
3746 return (jlong) ::_lseeki64(fd, offset, whence); |
|
3747 } |
|
3748 |
|
3749 // This method is a slightly reworked copy of JDK's sysNativePath |
|
3750 // from src/windows/hpi/src/path_md.c |
|
3751 |
|
3752 /* Convert a pathname to native format. On win32, this involves forcing all |
|
3753 separators to be '\\' rather than '/' (both are legal inputs, but Win95 |
|
3754 sometimes rejects '/') and removing redundant separators. The input path is |
|
3755 assumed to have been converted into the character encoding used by the local |
|
3756 system. Because this might be a double-byte encoding, care is taken to |
|
3757 treat double-byte lead characters correctly. |
|
3758 |
|
3759 This procedure modifies the given path in place, as the result is never |
|
3760 longer than the original. There is no error return; this operation always |
|
3761 succeeds. */ |
|
3762 char * os::native_path(char *path) { |
|
3763 char *src = path, *dst = path, *end = path; |
|
3764 char *colon = NULL; /* If a drive specifier is found, this will |
|
3765 point to the colon following the drive |
|
3766 letter */ |
|
3767 |
|
3768 /* Assumption: '/', '\\', ':', and drive letters are never lead bytes */ |
|
3769 assert(((!::IsDBCSLeadByte('/')) |
|
3770 && (!::IsDBCSLeadByte('\\')) |
|
3771 && (!::IsDBCSLeadByte(':'))), |
|
3772 "Illegal lead byte"); |
|
3773 |
|
3774 /* Check for leading separators */ |
|
3775 #define isfilesep(c) ((c) == '/' || (c) == '\\') |
|
3776 while (isfilesep(*src)) { |
|
3777 src++; |
|
3778 } |
|
3779 |
|
3780 if (::isalpha(*src) && !::IsDBCSLeadByte(*src) && src[1] == ':') { |
|
3781 /* Remove leading separators if followed by drive specifier. This |
|
3782 hack is necessary to support file URLs containing drive |
|
3783 specifiers (e.g., "file://c:/path"). As a side effect, |
|
3784 "/c:/path" can be used as an alternative to "c:/path". */ |
|
3785 *dst++ = *src++; |
|
3786 colon = dst; |
|
3787 *dst++ = ':'; |
|
3788 src++; |
|
3789 } else { |
|
3790 src = path; |
|
3791 if (isfilesep(src[0]) && isfilesep(src[1])) { |
|
3792 /* UNC pathname: Retain first separator; leave src pointed at |
|
3793 second separator so that further separators will be collapsed |
|
3794 into the second separator. The result will be a pathname |
|
3795 beginning with "\\\\" followed (most likely) by a host name. */ |
|
3796 src = dst = path + 1; |
|
3797 path[0] = '\\'; /* Force first separator to '\\' */ |
|
3798 } |
|
3799 } |
|
3800 |
|
3801 end = dst; |
|
3802 |
|
3803 /* Remove redundant separators from remainder of path, forcing all |
|
3804 separators to be '\\' rather than '/'. Also, single byte space |
|
3805 characters are removed from the end of the path because those |
|
3806 are not legal ending characters on this operating system. |
|
3807 */ |
|
3808 while (*src != '\0') { |
|
3809 if (isfilesep(*src)) { |
|
3810 *dst++ = '\\'; src++; |
|
3811 while (isfilesep(*src)) src++; |
|
3812 if (*src == '\0') { |
|
3813 /* Check for trailing separator */ |
|
3814 end = dst; |
|
3815 if (colon == dst - 2) break; /* "z:\\" */ |
|
3816 if (dst == path + 1) break; /* "\\" */ |
|
3817 if (dst == path + 2 && isfilesep(path[0])) { |
|
3818 /* "\\\\" is not collapsed to "\\" because "\\\\" marks the |
|
3819 beginning of a UNC pathname. Even though it is not, by |
|
3820 itself, a valid UNC pathname, we leave it as is in order |
|
3821 to be consistent with the path canonicalizer as well |
|
3822 as the win32 APIs, which treat this case as an invalid |
|
3823 UNC pathname rather than as an alias for the root |
|
3824 directory of the current drive. */ |
|
3825 break; |
|
3826 } |
|
3827 end = --dst; /* Path does not denote a root directory, so |
|
3828 remove trailing separator */ |
|
3829 break; |
|
3830 } |
|
3831 end = dst; |
|
3832 } else { |
|
3833 if (::IsDBCSLeadByte(*src)) { /* Copy a double-byte character */ |
|
3834 *dst++ = *src++; |
|
3835 if (*src) *dst++ = *src++; |
|
3836 end = dst; |
|
3837 } else { /* Copy a single-byte character */ |
|
3838 char c = *src++; |
|
3839 *dst++ = c; |
|
3840 /* Space is not a legal ending character */ |
|
3841 if (c != ' ') end = dst; |
|
3842 } |
|
3843 } |
|
3844 } |
|
3845 |
|
3846 *end = '\0'; |
|
3847 |
|
3848 /* For "z:", add "." to work around a bug in the C runtime library */ |
|
3849 if (colon == dst - 1) { |
|
3850 path[2] = '.'; |
|
3851 path[3] = '\0'; |
|
3852 } |
|
3853 |
|
3854 #ifdef DEBUG |
|
3855 jio_fprintf(stderr, "sysNativePath: %s\n", path); |
|
3856 #endif DEBUG |
|
3857 return path; |
|
3858 } |
|
3859 |
|
3860 // This code is a copy of JDK's sysSetLength |
|
3861 // from src/windows/hpi/src/sys_api_md.c |
|
3862 |
|
3863 int os::ftruncate(int fd, jlong length) { |
|
3864 HANDLE h = (HANDLE)::_get_osfhandle(fd); |
|
3865 long high = (long)(length >> 32); |
|
3866 DWORD ret; |
|
3867 |
|
3868 if (h == (HANDLE)(-1)) { |
|
3869 return -1; |
|
3870 } |
|
3871 |
|
3872 ret = ::SetFilePointer(h, (long)(length), &high, FILE_BEGIN); |
|
3873 if ((ret == 0xFFFFFFFF) && (::GetLastError() != NO_ERROR)) { |
|
3874 return -1; |
|
3875 } |
|
3876 |
|
3877 if (::SetEndOfFile(h) == FALSE) { |
|
3878 return -1; |
|
3879 } |
|
3880 |
|
3881 return 0; |
|
3882 } |
|
3883 |
|
3884 |
|
3885 // This code is a copy of JDK's sysSync |
|
3886 // from src/windows/hpi/src/sys_api_md.c |
|
3887 // except for the legacy workaround for a bug in Win 98 |
|
3888 |
|
3889 int os::fsync(int fd) { |
|
3890 HANDLE handle = (HANDLE)::_get_osfhandle(fd); |
|
3891 |
|
3892 if ( (!::FlushFileBuffers(handle)) && |
|
3893 (GetLastError() != ERROR_ACCESS_DENIED) ) { |
|
3894 /* from winerror.h */ |
|
3895 return -1; |
|
3896 } |
|
3897 return 0; |
|
3898 } |
|
3899 |
|
3900 static int nonSeekAvailable(int, long *); |
|
3901 static int stdinAvailable(int, long *); |
|
3902 |
|
3903 #define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR) |
|
3904 #define S_ISFIFO(mode) (((mode) & _S_IFIFO) == _S_IFIFO) |
|
3905 |
|
3906 // This code is a copy of JDK's sysAvailable |
|
3907 // from src/windows/hpi/src/sys_api_md.c |
|
3908 |
|
3909 int os::available(int fd, jlong *bytes) { |
|
3910 jlong cur, end; |
|
3911 struct _stati64 stbuf64; |
|
3912 |
|
3913 if (::_fstati64(fd, &stbuf64) >= 0) { |
|
3914 int mode = stbuf64.st_mode; |
|
3915 if (S_ISCHR(mode) || S_ISFIFO(mode)) { |
|
3916 int ret; |
|
3917 long lpbytes; |
|
3918 if (fd == 0) { |
|
3919 ret = stdinAvailable(fd, &lpbytes); |
|
3920 } else { |
|
3921 ret = nonSeekAvailable(fd, &lpbytes); |
|
3922 } |
|
3923 (*bytes) = (jlong)(lpbytes); |
|
3924 return ret; |
|
3925 } |
|
3926 if ((cur = ::_lseeki64(fd, 0L, SEEK_CUR)) == -1) { |
|
3927 return FALSE; |
|
3928 } else if ((end = ::_lseeki64(fd, 0L, SEEK_END)) == -1) { |
|
3929 return FALSE; |
|
3930 } else if (::_lseeki64(fd, cur, SEEK_SET) == -1) { |
|
3931 return FALSE; |
|
3932 } |
|
3933 *bytes = end - cur; |
|
3934 return TRUE; |
|
3935 } else { |
|
3936 return FALSE; |
|
3937 } |
|
3938 } |
|
3939 |
|
3940 // This code is a copy of JDK's nonSeekAvailable |
|
3941 // from src/windows/hpi/src/sys_api_md.c |
|
3942 |
|
3943 static int nonSeekAvailable(int fd, long *pbytes) { |
|
3944 /* This is used for available on non-seekable devices |
|
3945 * (like both named and anonymous pipes, such as pipes |
|
3946 * connected to an exec'd process). |
|
3947 * Standard Input is a special case. |
|
3948 * |
|
3949 */ |
|
3950 HANDLE han; |
|
3951 |
|
3952 if ((han = (HANDLE) ::_get_osfhandle(fd)) == (HANDLE)(-1)) { |
|
3953 return FALSE; |
|
3954 } |
|
3955 |
|
3956 if (! ::PeekNamedPipe(han, NULL, 0, NULL, (LPDWORD)pbytes, NULL)) { |
|
3957 /* PeekNamedPipe fails when at EOF. In that case we |
|
3958 * simply make *pbytes = 0 which is consistent with the |
|
3959 * behavior we get on Solaris when an fd is at EOF. |
|
3960 * The only alternative is to raise an Exception, |
|
3961 * which isn't really warranted. |
|
3962 */ |
|
3963 if (::GetLastError() != ERROR_BROKEN_PIPE) { |
|
3964 return FALSE; |
|
3965 } |
|
3966 *pbytes = 0; |
|
3967 } |
|
3968 return TRUE; |
|
3969 } |
|
3970 |
|
3971 #define MAX_INPUT_EVENTS 2000 |
|
3972 |
|
3973 // This code is a copy of JDK's stdinAvailable |
|
3974 // from src/windows/hpi/src/sys_api_md.c |
|
3975 |
|
3976 static int stdinAvailable(int fd, long *pbytes) { |
|
3977 HANDLE han; |
|
3978 DWORD numEventsRead = 0; /* Number of events read from buffer */ |
|
3979 DWORD numEvents = 0; /* Number of events in buffer */ |
|
3980 DWORD i = 0; /* Loop index */ |
|
3981 DWORD curLength = 0; /* Position marker */ |
|
3982 DWORD actualLength = 0; /* Number of bytes readable */ |
|
3983 BOOL error = FALSE; /* Error holder */ |
|
3984 INPUT_RECORD *lpBuffer; /* Pointer to records of input events */ |
|
3985 |
|
3986 if ((han = ::GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) { |
|
3987 return FALSE; |
|
3988 } |
|
3989 |
|
3990 /* Construct an array of input records in the console buffer */ |
|
3991 error = ::GetNumberOfConsoleInputEvents(han, &numEvents); |
|
3992 if (error == 0) { |
|
3993 return nonSeekAvailable(fd, pbytes); |
|
3994 } |
|
3995 |
|
3996 /* lpBuffer must fit into 64K or else PeekConsoleInput fails */ |
|
3997 if (numEvents > MAX_INPUT_EVENTS) { |
|
3998 numEvents = MAX_INPUT_EVENTS; |
|
3999 } |
|
4000 |
|
4001 lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD)); |
|
4002 if (lpBuffer == NULL) { |
|
4003 return FALSE; |
|
4004 } |
|
4005 |
|
4006 error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead); |
|
4007 if (error == 0) { |
|
4008 os::free(lpBuffer); |
|
4009 return FALSE; |
|
4010 } |
|
4011 |
|
4012 /* Examine input records for the number of bytes available */ |
|
4013 for(i=0; i<numEvents; i++) { |
|
4014 if (lpBuffer[i].EventType == KEY_EVENT) { |
|
4015 |
|
4016 KEY_EVENT_RECORD *keyRecord = (KEY_EVENT_RECORD *) |
|
4017 &(lpBuffer[i].Event); |
|
4018 if (keyRecord->bKeyDown == TRUE) { |
|
4019 CHAR *keyPressed = (CHAR *) &(keyRecord->uChar); |
|
4020 curLength++; |
|
4021 if (*keyPressed == '\r') { |
|
4022 actualLength = curLength; |
|
4023 } |
|
4024 } |
|
4025 } |
|
4026 } |
|
4027 |
|
4028 if(lpBuffer != NULL) { |
|
4029 os::free(lpBuffer); |
|
4030 } |
|
4031 |
|
4032 *pbytes = (long) actualLength; |
|
4033 return TRUE; |
|
4034 } |
3708 |
4035 |
3709 // Map a block of memory. |
4036 // Map a block of memory. |
3710 char* os::map_memory(int fd, const char* file_name, size_t file_offset, |
4037 char* os::map_memory(int fd, const char* file_name, size_t file_offset, |
3711 char *addr, size_t bytes, bool read_only, |
4038 char *addr, size_t bytes, bool read_only, |
3712 bool allow_exec) { |
4039 bool allow_exec) { |
4230 |
4557 |
4231 |
4558 |
4232 // We don't build a headless jre for Windows |
4559 // We don't build a headless jre for Windows |
4233 bool os::is_headless_jre() { return false; } |
4560 bool os::is_headless_jre() { return false; } |
4234 |
4561 |
|
4562 // OS_SocketInterface |
|
4563 // Not used on Windows |
|
4564 |
|
4565 // OS_SocketInterface |
|
4566 typedef struct hostent * (PASCAL FAR *ws2_ifn_ptr_t)(...); |
|
4567 ws2_ifn_ptr_t *get_host_by_name_fn = NULL; |
|
4568 |
|
4569 typedef CRITICAL_SECTION mutex_t; |
|
4570 #define mutexInit(m) InitializeCriticalSection(m) |
|
4571 #define mutexDestroy(m) DeleteCriticalSection(m) |
|
4572 #define mutexLock(m) EnterCriticalSection(m) |
|
4573 #define mutexUnlock(m) LeaveCriticalSection(m) |
|
4574 |
|
4575 static bool sockfnptrs_initialized = FALSE; |
|
4576 static mutex_t sockFnTableMutex; |
|
4577 |
|
4578 /* is Winsock2 loaded? better to be explicit than to rely on sockfnptrs */ |
|
4579 static bool winsock2Available = FALSE; |
|
4580 |
|
4581 |
|
4582 static void initSockFnTable() { |
|
4583 int (PASCAL FAR* WSAStartupPtr)(WORD, LPWSADATA); |
|
4584 WSADATA wsadata; |
|
4585 |
|
4586 ::mutexInit(&sockFnTableMutex); |
|
4587 ::mutexLock(&sockFnTableMutex); |
|
4588 |
|
4589 if (sockfnptrs_initialized == FALSE) { |
|
4590 HMODULE hWinsock; |
|
4591 |
|
4592 /* try to load Winsock2, and if that fails, load Winsock */ |
|
4593 hWinsock = ::LoadLibrary("ws2_32.dll"); |
|
4594 |
|
4595 if (hWinsock == NULL) { |
|
4596 jio_fprintf(stderr, "Could not load Winsock 2 (error: %d)\n", |
|
4597 ::GetLastError()); |
|
4598 return; |
|
4599 } |
|
4600 |
|
4601 /* If we loaded a DLL, then we might as well initialize it. */ |
|
4602 WSAStartupPtr = (int (PASCAL FAR *)(WORD, LPWSADATA)) |
|
4603 ::GetProcAddress(hWinsock, "WSAStartup"); |
|
4604 |
|
4605 if (WSAStartupPtr(MAKEWORD(1,1), &wsadata) != 0) { |
|
4606 jio_fprintf(stderr, "Could not initialize Winsock\n"); |
|
4607 } |
|
4608 |
|
4609 get_host_by_name_fn |
|
4610 = (ws2_ifn_ptr_t*) GetProcAddress(hWinsock, "gethostbyname"); |
|
4611 } |
|
4612 |
|
4613 assert(get_host_by_name_fn != NULL, |
|
4614 "gethostbyname function not found"); |
|
4615 sockfnptrs_initialized = TRUE; |
|
4616 ::mutexUnlock(&sockFnTableMutex); |
|
4617 } |
|
4618 |
|
4619 struct hostent* os::get_host_by_name(char* name) { |
|
4620 if (!sockfnptrs_initialized) { |
|
4621 initSockFnTable(); |
|
4622 } |
|
4623 |
|
4624 assert(sockfnptrs_initialized == TRUE && get_host_by_name_fn != NULL, |
|
4625 "sockfnptrs is not initialized or pointer to gethostbyname function is NULL"); |
|
4626 return (*get_host_by_name_fn)(name); |
|
4627 } |
|
4628 |
|
4629 |
|
4630 int os::socket_close(int fd) { |
|
4631 ShouldNotReachHere(); |
|
4632 return 0; |
|
4633 } |
|
4634 |
|
4635 int os::socket_available(int fd, jint *pbytes) { |
|
4636 ShouldNotReachHere(); |
|
4637 return 0; |
|
4638 } |
|
4639 |
|
4640 int os::socket(int domain, int type, int protocol) { |
|
4641 ShouldNotReachHere(); |
|
4642 return 0; |
|
4643 } |
|
4644 |
|
4645 int os::listen(int fd, int count) { |
|
4646 ShouldNotReachHere(); |
|
4647 return 0; |
|
4648 } |
|
4649 |
|
4650 int os::connect(int fd, struct sockaddr *him, int len) { |
|
4651 ShouldNotReachHere(); |
|
4652 return 0; |
|
4653 } |
|
4654 |
|
4655 int os::accept(int fd, struct sockaddr *him, int *len) { |
|
4656 ShouldNotReachHere(); |
|
4657 return 0; |
|
4658 } |
|
4659 |
|
4660 int os::sendto(int fd, char *buf, int len, int flags, |
|
4661 struct sockaddr *to, int tolen) { |
|
4662 ShouldNotReachHere(); |
|
4663 return 0; |
|
4664 } |
|
4665 |
|
4666 int os::recvfrom(int fd, char *buf, int nBytes, int flags, |
|
4667 sockaddr *from, int *fromlen) { |
|
4668 ShouldNotReachHere(); |
|
4669 return 0; |
|
4670 } |
|
4671 |
|
4672 int os::recv(int fd, char *buf, int nBytes, int flags) { |
|
4673 ShouldNotReachHere(); |
|
4674 return 0; |
|
4675 } |
|
4676 |
|
4677 int os::send(int fd, char *buf, int nBytes, int flags) { |
|
4678 ShouldNotReachHere(); |
|
4679 return 0; |
|
4680 } |
|
4681 |
|
4682 int os::raw_send(int fd, char *buf, int nBytes, int flags) { |
|
4683 ShouldNotReachHere(); |
|
4684 return 0; |
|
4685 } |
|
4686 |
|
4687 int os::timeout(int fd, long timeout) { |
|
4688 ShouldNotReachHere(); |
|
4689 return 0; |
|
4690 } |
|
4691 |
|
4692 int os::get_host_name(char* name, int namelen) { |
|
4693 ShouldNotReachHere(); |
|
4694 return 0; |
|
4695 } |
|
4696 |
|
4697 int os::socket_shutdown(int fd, int howto) { |
|
4698 ShouldNotReachHere(); |
|
4699 return 0; |
|
4700 } |
|
4701 |
|
4702 int os::bind(int fd, struct sockaddr *him, int len) { |
|
4703 ShouldNotReachHere(); |
|
4704 return 0; |
|
4705 } |
|
4706 |
|
4707 int os::get_sock_name(int fd, struct sockaddr *him, int *len) { |
|
4708 ShouldNotReachHere(); |
|
4709 return 0; |
|
4710 } |
|
4711 |
|
4712 int os::get_sock_opt(int fd, int level, int optname, |
|
4713 char *optval, int* optlen) { |
|
4714 ShouldNotReachHere(); |
|
4715 return 0; |
|
4716 } |
|
4717 |
|
4718 int os::set_sock_opt(int fd, int level, int optname, |
|
4719 const char *optval, int optlen) { |
|
4720 ShouldNotReachHere(); |
|
4721 return 0; |
|
4722 } |