OLD | NEW |
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 /* This Source Code Form is subject to the terms of the Mozilla Public | 2 /* This Source Code Form is subject to the terms of the Mozilla Public |
3 * License, v. 2.0. If a copy of the MPL was not distributed with this | 3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | 5 |
6 #include "primpl.h" | 6 #include "primpl.h" |
7 | 7 |
8 #include <string.h> | 8 #include <string.h> |
9 #include <signal.h> | 9 #include <signal.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
11 #include <fcntl.h> | 11 #include <fcntl.h> |
12 #include <sys/types.h> | 12 #include <sys/types.h> |
13 #include <sys/socket.h> | 13 #include <sys/socket.h> |
14 #include <sys/time.h> | 14 #include <sys/time.h> |
15 #include <sys/ioctl.h> | 15 #include <sys/ioctl.h> |
16 #include <sys/mman.h> | 16 #include <sys/mman.h> |
17 #include <unistd.h> | 17 #include <unistd.h> |
18 #include <sys/utsname.h> | 18 #include <sys/utsname.h> |
19 | 19 |
20 #ifdef _PR_POLL_AVAILABLE | 20 #ifdef _PR_POLL_AVAILABLE |
21 #include <poll.h> | 21 #include <poll.h> |
22 #endif | 22 #endif |
23 | 23 |
24 /* To get FIONREAD */ | 24 /* To get FIONREAD */ |
25 #if defined(NCR) || defined(UNIXWARE) || defined(NEC) || defined(SNI) \ | 25 #if defined(UNIXWARE) |
26 || defined(SONY) | |
27 #include <sys/filio.h> | 26 #include <sys/filio.h> |
28 #endif | 27 #endif |
29 | 28 |
30 #if defined(NTO) | 29 #if defined(NTO) |
31 #include <sys/statvfs.h> | 30 #include <sys/statvfs.h> |
32 #endif | 31 #endif |
33 | 32 |
34 /* | 33 /* |
35 * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or | 34 * Make sure _PRSockLen_t is 32-bit, because we will cast a PRUint32* or |
36 * PRInt32* pointer to a _PRSockLen_t* pointer. | 35 * PRInt32* pointer to a _PRSockLen_t* pointer. |
37 */ | 36 */ |
38 #if defined(HAVE_SOCKLEN_T) \ | 37 #if defined(HAVE_SOCKLEN_T) \ |
39 || (defined(__GLIBC__) && __GLIBC__ >= 2) | 38 || (defined(__GLIBC__) && __GLIBC__ >= 2) |
40 #define _PRSockLen_t socklen_t | 39 #define _PRSockLen_t socklen_t |
41 #elif defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \ | 40 #elif defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \ |
42 || defined(AIX4_1) || defined(LINUX) || defined(SONY) \ | 41 || defined(AIX4_1) || defined(LINUX) \ |
43 || defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \ | 42 || defined(BSDI) || defined(SCO) \ |
44 || defined(SUNOS4) || defined(NCR) || defined(DARWIN) \ | 43 || defined(DARWIN) \ |
45 || defined(NEXTSTEP) || defined(QNX) | 44 || defined(QNX) |
46 #define _PRSockLen_t int | 45 #define _PRSockLen_t int |
47 #elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \ | 46 #elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \ |
48 || defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \ | 47 || defined(NETBSD) || defined(OPENBSD) || defined(UNIXWARE) \ |
49 || defined(DGUX) || defined(NTO) || defined(RISCOS) | 48 || defined(DGUX) || defined(NTO) || defined(RISCOS) |
50 #define _PRSockLen_t size_t | 49 #define _PRSockLen_t size_t |
51 #else | 50 #else |
52 #error "Cannot determine architecture" | 51 #error "Cannot determine architecture" |
53 #endif | 52 #endif |
54 | 53 |
55 /* | 54 /* |
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 { | 760 { |
762 PRInt32 osfd = fd->secret->md.osfd; | 761 PRInt32 osfd = fd->secret->md.osfd; |
763 PRInt32 rv, err; | 762 PRInt32 rv, err; |
764 PRThread *me = _PR_MD_CURRENT_THREAD(); | 763 PRThread *me = _PR_MD_CURRENT_THREAD(); |
765 | 764 |
766 /* | 765 /* |
767 * Many OS's (Solaris, Unixware) have a broken recv which won't read | 766 * Many OS's (Solaris, Unixware) have a broken recv which won't read |
768 * from socketpairs. As long as we don't use flags on socketpairs, this | 767 * from socketpairs. As long as we don't use flags on socketpairs, this |
769 * is a decent fix. - mikep | 768 * is a decent fix. - mikep |
770 */ | 769 */ |
771 #if defined(UNIXWARE) || defined(SOLARIS) || defined(NCR) | 770 #if defined(UNIXWARE) || defined(SOLARIS) |
772 while ((rv = read(osfd,buf,amount)) == -1) { | 771 while ((rv = read(osfd,buf,amount)) == -1) { |
773 #else | 772 #else |
774 while ((rv = recv(osfd,buf,amount,flags)) == -1) { | 773 while ((rv = recv(osfd,buf,amount,flags)) == -1) { |
775 #endif | 774 #endif |
776 err = _MD_ERRNO(); | 775 err = _MD_ERRNO(); |
777 if ((err == EAGAIN) || (err == EWOULDBLOCK)) { | 776 if ((err == EAGAIN) || (err == EWOULDBLOCK)) { |
778 if (fd->secret->nonblocking) { | 777 if (fd->secret->nonblocking) { |
779 break; | 778 break; |
780 } | 779 } |
781 if (!_PR_IS_NATIVE_THREAD(me)) { | 780 if (!_PR_IS_NATIVE_THREAD(me)) { |
(...skipping 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2170 return; | 2169 return; |
2171 } | 2170 } |
2172 flags = fcntl(osfd, F_GETFL, 0); | 2171 flags = fcntl(osfd, F_GETFL, 0); |
2173 | 2172 |
2174 /* | 2173 /* |
2175 * Use O_NONBLOCK (POSIX-style non-blocking I/O) whenever possible. | 2174 * Use O_NONBLOCK (POSIX-style non-blocking I/O) whenever possible. |
2176 * On SunOS 4, we must use FNDELAY (BSD-style non-blocking I/O), | 2175 * On SunOS 4, we must use FNDELAY (BSD-style non-blocking I/O), |
2177 * otherwise connect() still blocks and can be interrupted by SIGALRM. | 2176 * otherwise connect() still blocks and can be interrupted by SIGALRM. |
2178 */ | 2177 */ |
2179 | 2178 |
2180 #ifdef SUNOS4 | |
2181 fcntl(osfd, F_SETFL, flags | FNDELAY); | |
2182 #else | |
2183 fcntl(osfd, F_SETFL, flags | O_NONBLOCK); | 2179 fcntl(osfd, F_SETFL, flags | O_NONBLOCK); |
2184 #endif | |
2185 } | 2180 } |
2186 | 2181 |
2187 PRInt32 _MD_open(const char *name, PRIntn flags, PRIntn mode) | 2182 PRInt32 _MD_open(const char *name, PRIntn flags, PRIntn mode) |
2188 { | 2183 { |
2189 PRInt32 osflags; | 2184 PRInt32 osflags; |
2190 PRInt32 rv, err; | 2185 PRInt32 rv, err; |
2191 | 2186 |
2192 if (flags & PR_RDWR) { | 2187 if (flags & PR_RDWR) { |
2193 osflags = O_RDWR; | 2188 osflags = O_RDWR; |
2194 } else if (flags & PR_WRONLY) { | 2189 } else if (flags & PR_WRONLY) { |
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3010 | 3005 |
3011 GETTIMEOFDAY(&tv); | 3006 GETTIMEOFDAY(&tv); |
3012 LL_I2L(s2us, PR_USEC_PER_SEC); | 3007 LL_I2L(s2us, PR_USEC_PER_SEC); |
3013 LL_I2L(s, tv.tv_sec); | 3008 LL_I2L(s, tv.tv_sec); |
3014 LL_I2L(us, tv.tv_usec); | 3009 LL_I2L(us, tv.tv_usec); |
3015 LL_MUL(s, s, s2us); | 3010 LL_MUL(s, s, s2us); |
3016 LL_ADD(s, s, us); | 3011 LL_ADD(s, s, us); |
3017 return s; | 3012 return s; |
3018 } | 3013 } |
3019 | 3014 |
| 3015 #if defined(_MD_INTERVAL_USE_GTOD) |
| 3016 /* |
| 3017 * This version of interval times is based on the time of day |
| 3018 * capability offered by the system. This isn't valid for two reasons: |
| 3019 * 1) The time of day is neither linear nor montonically increasing |
| 3020 * 2) The units here are milliseconds. That's not appropriate for our use. |
| 3021 */ |
3020 PRIntervalTime _PR_UNIX_GetInterval() | 3022 PRIntervalTime _PR_UNIX_GetInterval() |
3021 { | 3023 { |
3022 struct timeval time; | 3024 struct timeval time; |
3023 PRIntervalTime ticks; | 3025 PRIntervalTime ticks; |
3024 | 3026 |
3025 (void)GETTIMEOFDAY(&time); /* fallicy of course */ | 3027 (void)GETTIMEOFDAY(&time); /* fallicy of course */ |
3026 ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; /* that's in milliseconds
*/ | 3028 ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; /* that's in milliseconds
*/ |
3027 ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC; /* so's that */ | 3029 ticks += (PRUint32)time.tv_usec / PR_USEC_PER_MSEC; /* so's that */ |
3028 return ticks; | 3030 return ticks; |
3029 } /* _PR_SUNOS_GetInterval */ | 3031 } /* _PR_UNIX_GetInterval */ |
3030 | 3032 |
3031 PRIntervalTime _PR_UNIX_TicksPerSecond() | 3033 PRIntervalTime _PR_UNIX_TicksPerSecond() |
3032 { | 3034 { |
3033 return 1000; /* this needs some work :) */ | 3035 return 1000; /* this needs some work :) */ |
3034 } | 3036 } |
| 3037 #endif |
| 3038 |
| 3039 #if defined(HAVE_CLOCK_MONOTONIC) |
| 3040 PRIntervalTime _PR_UNIX_GetInterval2() |
| 3041 { |
| 3042 struct timespec time; |
| 3043 PRIntervalTime ticks; |
| 3044 |
| 3045 if (clock_gettime(CLOCK_MONOTONIC, &time) != 0) { |
| 3046 fprintf(stderr, "clock_gettime failed: %d\n", errno); |
| 3047 abort(); |
| 3048 } |
| 3049 |
| 3050 ticks = (PRUint32)time.tv_sec * PR_MSEC_PER_SEC; |
| 3051 ticks += (PRUint32)time.tv_nsec / PR_NSEC_PER_MSEC; |
| 3052 return ticks; |
| 3053 } |
| 3054 |
| 3055 PRIntervalTime _PR_UNIX_TicksPerSecond2() |
| 3056 { |
| 3057 return 1000; |
| 3058 } |
| 3059 #endif |
3035 | 3060 |
3036 #if !defined(_PR_PTHREADS) | 3061 #if !defined(_PR_PTHREADS) |
3037 /* | 3062 /* |
3038 * Wait for I/O on multiple descriptors. | 3063 * Wait for I/O on multiple descriptors. |
3039 * | 3064 * |
3040 * Return 0 if timed out, return -1 if interrupted, | 3065 * Return 0 if timed out, return -1 if interrupted, |
3041 * else return the number of ready descriptors. | 3066 * else return the number of ready descriptors. |
3042 */ | 3067 */ |
3043 PRInt32 _PR_WaitForMultipleFDs( | 3068 PRInt32 _PR_WaitForMultipleFDs( |
3044 _PRUnixPollDesc *unixpds, | 3069 _PRUnixPollDesc *unixpds, |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3285 if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, | 3310 if (getsockopt(osfd, SOL_SOCKET, SO_ERROR, |
3286 (char *) &err, &optlen) == -1) { | 3311 (char *) &err, &optlen) == -1) { |
3287 return errno; | 3312 return errno; |
3288 } else { | 3313 } else { |
3289 return err; | 3314 return err; |
3290 } | 3315 } |
3291 } | 3316 } |
3292 } else { | 3317 } else { |
3293 return ECONNREFUSED; | 3318 return ECONNREFUSED; |
3294 } | 3319 } |
3295 #elif defined(NCR) || defined(UNIXWARE) || defined(SNI) || defined(NEC) | 3320 #elif defined(UNIXWARE) |
3296 /* | 3321 /* |
3297 * getsockopt() fails with EPIPE, so use getmsg() instead. | 3322 * getsockopt() fails with EPIPE, so use getmsg() instead. |
3298 */ | 3323 */ |
3299 | 3324 |
3300 int rv; | 3325 int rv; |
3301 int flags = 0; | 3326 int flags = 0; |
3302 rv = getmsg(osfd, NULL, NULL, &flags); | 3327 rv = getmsg(osfd, NULL, NULL, &flags); |
3303 PR_ASSERT(-1 == rv || 0 == rv); | 3328 PR_ASSERT(-1 == rv || 0 == rv); |
3304 if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) { | 3329 if (-1 == rv && errno != EAGAIN && errno != EWOULDBLOCK) { |
3305 return errno; | 3330 return errno; |
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3740 rv++; | 3765 rv++; |
3741 } | 3766 } |
3742 } | 3767 } |
3743 PR_ASSERT(rv > 0); | 3768 PR_ASSERT(rv > 0); |
3744 } | 3769 } |
3745 PR_ASSERT(-1 != timeout || rv != 0); | 3770 PR_ASSERT(-1 != timeout || rv != 0); |
3746 | 3771 |
3747 return rv; | 3772 return rv; |
3748 } | 3773 } |
3749 #endif /* _PR_NEED_FAKE_POLL */ | 3774 #endif /* _PR_NEED_FAKE_POLL */ |
OLD | NEW |