1a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 2a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (C) 2011-2012 Christian Beier <dontmind@freeshell.org> 3a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. 4a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 5a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This is free software; you can redistribute it and/or modify 6a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * it under the terms of the GNU General Public License as published by 7a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * the Free Software Foundation; either version 2 of the License, or 8a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * (at your option) any later version. 9a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 10a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * This software is distributed in the hope that it will be useful, 11a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * but WITHOUT ANY WARRANTY; without even the implied warranty of 12a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * GNU General Public License for more details. 14a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * 15a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * You should have received a copy of the GNU General Public License 16a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * along with this software; if not, write to the Free Software 17a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 18a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * USA. 19a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 20a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 21a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 22a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * listen.c - listen for incoming connections 23a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 24a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 25a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __STRICT_ANSI__ 26a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define _BSD_SOURCE 27a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 28a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <unistd.h> 29a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/types.h> 30a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __MINGW32__ 31a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#define close closesocket 32a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <winsock2.h> 33a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#undef max 34a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 35a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/wait.h> 36a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/utsname.h> 37a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 38a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <sys/time.h> 39a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#include <rfb/rfbclient.h> 40a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 41a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 42a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * listenForIncomingConnections() - listen for incoming connections from 43a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * servers, and fork a new process to deal with each connection. 44a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 45a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 46a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatvoid 47a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatlistenForIncomingConnections(rfbClient* client) 48a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 49a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef __MINGW32__ 50a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* FIXME */ 51a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientErr("listenForIncomingConnections on MinGW32 NOT IMPLEMENTED\n"); 52a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 53a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#else 54a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int listenSocket, listen6Socket = -1; 55a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd_set fds; 56a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 57a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->listenSpecified = TRUE; 58a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 59a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat listenSocket = ListenAtTcpPortAndAddress(client->listenPort, client->listenAddress); 60a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 61a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if ((listenSocket < 0)) 62a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 63a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 64a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("%s -listen: Listening on port %d\n", 65a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->programName,client->listenPort); 66a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("%s -listen: Command line errors are not reported until " 67a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "a connection comes in.\n", client->programName); 68a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 69a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */ 70a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* only do IPv6 listen of listen6Port is set */ 71a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (client->listen6Port > 0) 72a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 73a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat listen6Socket = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address); 74a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 75a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (listen6Socket < 0) 76a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 77a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 78a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("%s -listen: Listening on IPV6 port %d\n", 79a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->programName,client->listenPort); 80a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("%s -listen: Command line errors are not reported until " 81a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "a connection comes in.\n", client->programName); 82a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 83a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 84a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 85a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while (TRUE) { 86a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int r; 87a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* reap any zombies */ 88a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int status, pid; 89a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat while ((pid= wait3(&status, WNOHANG, (struct rusage *)0))>0); 90a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 91a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* TODO: callback for discard any events (like X11 events) */ 92a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 93a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_ZERO(&fds); 94a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 95a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(listenSocket >= 0) 96a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_SET(listenSocket, &fds); 97a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(listen6Socket >= 0) 98a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_SET(listen6Socket, &fds); 99a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 100a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat r = select(max(listenSocket, listen6Socket)+1, &fds, NULL, NULL, NULL); 101a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 102a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (r > 0) { 103a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (FD_ISSET(listenSocket, &fds)) 104a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->sock = AcceptTcpConnection(client->listenSock); 105a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if (FD_ISSET(listen6Socket, &fds)) 106a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->sock = AcceptTcpConnection(client->listen6Sock); 107a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 108a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (client->sock < 0) 109a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 110a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!SetNonBlocking(client->sock)) 111a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 112a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 113a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* Now fork off a new process to deal with it... */ 114a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 115a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat switch (fork()) { 116a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 117a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case -1: 118a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientErr("fork\n"); 119a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 120a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 121a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat case 0: 122a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* child - return to caller */ 123a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(listenSocket); 124a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(listen6Socket); 125a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return; 126a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 127a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat default: 128a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* parent - go round and listen again */ 129a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(client->sock); 130a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat break; 131a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 132a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 133a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 134a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 135a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 136a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 137a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 138a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 139a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat/* 140a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * listenForIncomingConnectionsNoFork() - listen for incoming connections 141a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * from servers, but DON'T fork, instead just wait timeout microseconds. 142a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * If timeout is negative, block indefinitly. 143a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * Returns 1 on success (there was an incoming connection on the listen socket 144a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat * and we accepted it successfully), -1 on error, 0 on timeout. 145a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat */ 146a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 147a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehatint 148a430b2b5ca4f0967836f5820e8f03adc17fc0a24San MehatlistenForIncomingConnectionsNoFork(rfbClient* client, int timeout) 149a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat{ 150a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat fd_set fds; 151a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat struct timeval to; 152a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat int r; 153a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 154a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat to.tv_sec= timeout / 1000000; 155a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat to.tv_usec= timeout % 1000000; 156a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 157a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->listenSpecified = TRUE; 158a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 159a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (client->listenSock < 0) 160a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 161a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->listenSock = ListenAtTcpPortAndAddress(client->listenPort, client->listenAddress); 162a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 163a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (client->listenSock < 0) 164a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 165a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 166a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("%s -listennofork: Listening on port %d\n", 167a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->programName,client->listenPort); 168a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("%s -listennofork: Command line errors are not reported until " 169a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "a connection comes in.\n", client->programName); 170a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 171a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 172a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */ 173a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* only do IPv6 listen of listen6Port is set */ 174a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (client->listen6Port > 0 && client->listen6Sock < 0) 175a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 176a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->listen6Sock = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address); 177a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 178a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (client->listen6Sock < 0) 179a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 180a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 181a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("%s -listennofork: Listening on IPV6 port %d\n", 182a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->programName,client->listenPort); 183a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat rfbClientLog("%s -listennofork: Command line errors are not reported until " 184a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat "a connection comes in.\n", client->programName); 185a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 186a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat#endif 187a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 188a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_ZERO(&fds); 189a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 190a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(client->listenSock >= 0) 191a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_SET(client->listenSock, &fds); 192a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(client->listen6Sock >= 0) 193a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat FD_SET(client->listen6Sock, &fds); 194a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 195a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (timeout < 0) 196a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat r = select(max(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, NULL); 197a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else 198a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat r = select(max(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, &to); 199a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 200a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (r > 0) 201a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat { 202a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (FD_ISSET(client->listenSock, &fds)) 203a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->sock = AcceptTcpConnection(client->listenSock); 204a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat else if (FD_ISSET(client->listen6Sock, &fds)) 205a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->sock = AcceptTcpConnection(client->listen6Sock); 206a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 207a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (client->sock < 0) 208a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 209a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if (!SetNonBlocking(client->sock)) 210a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return -1; 211a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 212a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(client->listenSock >= 0) { 213a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(client->listenSock); 214a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->listenSock = -1; 215a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 216a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat if(client->listen6Sock >= 0) { 217a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat close(client->listen6Sock); 218a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat client->listen6Sock = -1; 219a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 220a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return r; 221a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat } 222a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 223a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat /* r is now either 0 (timeout) or -1 (error) */ 224a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat return r; 225a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat} 226a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 227a430b2b5ca4f0967836f5820e8f03adc17fc0a24San Mehat 228