diff options
| author | Jason Rumney | 2002-05-03 20:40:03 +0000 |
|---|---|---|
| committer | Jason Rumney | 2002-05-03 20:40:03 +0000 |
| commit | ecd270eb5c9f5bea4c9fd9ee3fec78d61759a0e2 (patch) | |
| tree | a9a35a425dda36d8f202d2d5d0d33eb8f7c0f098 /src | |
| parent | 51f635c4cf429aa0ecdc4e4383ae7ed7f2ce52cf (diff) | |
| download | emacs-ecd270eb5c9f5bea4c9fd9ee3fec78d61759a0e2.tar.gz emacs-ecd270eb5c9f5bea4c9fd9ee3fec78d61759a0e2.zip | |
(sys_getpeername, fcntl): New functions.
(_sys_read_ahead): Temporarily block on non-blocking sockets.
Diffstat (limited to 'src')
| -rw-r--r-- | src/w32.c | 75 |
1 files changed, 73 insertions, 2 deletions
| @@ -84,6 +84,7 @@ Boston, MA 02111-1307, USA. | |||
| 84 | #undef gethostname | 84 | #undef gethostname |
| 85 | #undef gethostbyname | 85 | #undef gethostbyname |
| 86 | #undef getservbyname | 86 | #undef getservbyname |
| 87 | #undef getpeername | ||
| 87 | #undef shutdown | 88 | #undef shutdown |
| 88 | #undef setsockopt | 89 | #undef setsockopt |
| 89 | #undef listen | 90 | #undef listen |
| @@ -2424,7 +2425,7 @@ unsigned long (PASCAL *pfn_inet_addr) (const char * cp); | |||
| 2424 | int (PASCAL *pfn_gethostname) (char * name, int namelen); | 2425 | int (PASCAL *pfn_gethostname) (char * name, int namelen); |
| 2425 | struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); | 2426 | struct hostent * (PASCAL *pfn_gethostbyname) (const char * name); |
| 2426 | struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto); | 2427 | struct servent * (PASCAL *pfn_getservbyname) (const char * name, const char * proto); |
| 2427 | 2428 | int (PASCAL *pfn_getpeername) (SOCKET s, struct sockaddr *addr, int * namelen); | |
| 2428 | int (PASCAL *pfn_setsockopt) (SOCKET s, int level, int optname, | 2429 | int (PASCAL *pfn_setsockopt) (SOCKET s, int level, int optname, |
| 2429 | const char * optval, int optlen); | 2430 | const char * optval, int optlen); |
| 2430 | int (PASCAL *pfn_listen) (SOCKET s, int backlog); | 2431 | int (PASCAL *pfn_listen) (SOCKET s, int backlog); |
| @@ -2504,6 +2505,7 @@ init_winsock (int load_now) | |||
| 2504 | LOAD_PROC( gethostname ); | 2505 | LOAD_PROC( gethostname ); |
| 2505 | LOAD_PROC( gethostbyname ); | 2506 | LOAD_PROC( gethostbyname ); |
| 2506 | LOAD_PROC( getservbyname ); | 2507 | LOAD_PROC( getservbyname ); |
| 2508 | LOAD_PROC( getpeername ); | ||
| 2507 | LOAD_PROC( WSACleanup ); | 2509 | LOAD_PROC( WSACleanup ); |
| 2508 | LOAD_PROC( setsockopt ); | 2510 | LOAD_PROC( setsockopt ); |
| 2509 | LOAD_PROC( listen ); | 2511 | LOAD_PROC( listen ); |
| @@ -2923,6 +2925,28 @@ sys_getservbyname(const char * name, const char * proto) | |||
| 2923 | } | 2925 | } |
| 2924 | 2926 | ||
| 2925 | int | 2927 | int |
| 2928 | sys_getpeername (int s, struct sockaddr *addr, int * namelen) | ||
| 2929 | { | ||
| 2930 | if (winsock_lib == NULL) | ||
| 2931 | { | ||
| 2932 | h_errno = ENETDOWN; | ||
| 2933 | return SOCKET_ERROR; | ||
| 2934 | } | ||
| 2935 | |||
| 2936 | check_errno (); | ||
| 2937 | if (fd_info[s].flags & FILE_SOCKET) | ||
| 2938 | { | ||
| 2939 | int rc = pfn_getpeername (SOCK_HANDLE (s), addr, namelen); | ||
| 2940 | if (rc == SOCKET_ERROR) | ||
| 2941 | set_errno (); | ||
| 2942 | return rc; | ||
| 2943 | } | ||
| 2944 | h_errno = ENOTSOCK; | ||
| 2945 | return SOCKET_ERROR; | ||
| 2946 | } | ||
| 2947 | |||
| 2948 | |||
| 2949 | int | ||
| 2926 | sys_shutdown (int s, int how) | 2950 | sys_shutdown (int s, int how) |
| 2927 | { | 2951 | { |
| 2928 | if (winsock_lib == NULL) | 2952 | if (winsock_lib == NULL) |
| @@ -3074,6 +3098,40 @@ sys_sendto (int s, const char * buf, int len, int flags, | |||
| 3074 | return SOCKET_ERROR; | 3098 | return SOCKET_ERROR; |
| 3075 | } | 3099 | } |
| 3076 | 3100 | ||
| 3101 | /* Windows does not have an fcntl function. Provide an implementation | ||
| 3102 | solely for making sockets non-blocking. */ | ||
| 3103 | int | ||
| 3104 | fcntl (int s, int cmd, int options) | ||
| 3105 | { | ||
| 3106 | if (winsock_lib == NULL) | ||
| 3107 | { | ||
| 3108 | h_errno = ENETDOWN; | ||
| 3109 | return -1; | ||
| 3110 | } | ||
| 3111 | |||
| 3112 | check_errno (); | ||
| 3113 | if (fd_info[s].flags & FILE_SOCKET) | ||
| 3114 | { | ||
| 3115 | if (cmd == F_SETFL && options == O_NDELAY) | ||
| 3116 | { | ||
| 3117 | unsigned long nblock = 1; | ||
| 3118 | int rc = pfn_ioctlsocket (SOCK_HANDLE (s), FIONBIO, &nblock); | ||
| 3119 | if (rc == SOCKET_ERROR) | ||
| 3120 | set_errno(); | ||
| 3121 | /* Keep track of the fact that we set this to non-blocking. */ | ||
| 3122 | fd_info[s].flags |= FILE_NDELAY; | ||
| 3123 | return rc; | ||
| 3124 | } | ||
| 3125 | else | ||
| 3126 | { | ||
| 3127 | h_errno = EINVAL; | ||
| 3128 | return SOCKET_ERROR; | ||
| 3129 | } | ||
| 3130 | } | ||
| 3131 | h_errno = ENOTSOCK; | ||
| 3132 | return SOCKET_ERROR; | ||
| 3133 | } | ||
| 3134 | |||
| 3077 | #endif /* HAVE_SOCKETS */ | 3135 | #endif /* HAVE_SOCKETS */ |
| 3078 | 3136 | ||
| 3079 | 3137 | ||
| @@ -3257,7 +3315,20 @@ _sys_read_ahead (int fd) | |||
| 3257 | } | 3315 | } |
| 3258 | #ifdef HAVE_SOCKETS | 3316 | #ifdef HAVE_SOCKETS |
| 3259 | else if (fd_info[fd].flags & FILE_SOCKET) | 3317 | else if (fd_info[fd].flags & FILE_SOCKET) |
| 3260 | rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0); | 3318 | { |
| 3319 | unsigned long nblock = 0; | ||
| 3320 | /* We always want this to block, so temporarily disable NDELAY. */ | ||
| 3321 | if (fd_info[fd].flags & FILE_NDELAY) | ||
| 3322 | pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock); | ||
| 3323 | |||
| 3324 | rc = pfn_recv (SOCK_HANDLE (fd), &cp->chr, sizeof (char), 0); | ||
| 3325 | |||
| 3326 | if (fd_info[fd].flags & FILE_NDELAY) | ||
| 3327 | { | ||
| 3328 | nblock = 1; | ||
| 3329 | pfn_ioctlsocket (SOCK_HANDLE (fd), FIONBIO, &nblock); | ||
| 3330 | } | ||
| 3331 | } | ||
| 3261 | #endif | 3332 | #endif |
| 3262 | 3333 | ||
| 3263 | if (rc == sizeof (char)) | 3334 | if (rc == sizeof (char)) |