FSConnServ.c revision ba6a1819
1/* $Xorg: FSConnServ.c,v 1.4 2001/02/09 02:03:25 xorgcvs Exp $ */ 2 3/* 4 * Copyright 1990 Network Computing Devices; 5 * Portions Copyright 1987 by Digital Equipment Corporation 6 * 7 * Permission to use, copy, modify, distribute, and sell this software 8 * and its documentation for any purpose is hereby granted without fee, 9 * provided that the above copyright notice appear in all copies and 10 * that both that copyright notice and this permission notice appear 11 * in supporting documentation, and that the names of Network Computing 12 * Devices or Digital not be used in advertising or publicity pertaining 13 * to distribution of the software without specific, written prior 14 * permission. Network Computing Devices or Digital make no representations 15 * about the suitability of this software for any purpose. It is provided 16 * "as is" without express or implied warranty. 17 * 18 * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH 19 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 20 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES 21 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES 22 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 23 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 24 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 25 * SOFTWARE. 26 */ 27 28/* 29 30Copyright 1987, 1994, 1998 The Open Group 31 32Permission to use, copy, modify, distribute, and sell this software and its 33documentation for any purpose is hereby granted without fee, provided that 34the above copyright notice appear in all copies and that both that 35copyright notice and this permission notice appear in supporting 36documentation. 37 38The above copyright notice and this permission notice shall be included in 39all copies or substantial portions of the Software. 40 41THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 45AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 46CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 47 48Except as contained in this notice, the name of The Open Group shall not be 49used in advertising or otherwise to promote the sale, use or other dealings 50in this Software without prior written authorization from The Open Group. 51 52*/ 53/* $XFree86: xc/lib/FS/FSConnServ.c,v 3.10 2001/10/28 03:32:27 tsi Exp $ */ 54 55#ifdef HAVE_CONFIG_H 56#include <config.h> 57#endif 58#include "FSlibint.h" 59#include <stdio.h> 60#include "X11/Xpoll.h" 61#ifdef NCD 62#include <fcntl.h> 63#endif 64#ifdef WIN32 65#define ECHECK(err) (WSAGetLastError() == err) 66#else 67#ifdef ISC 68#define ECHECK(err) ((errno == err) || errno == EAGAIN || errno == EWOULDBLOCK) 69#else 70#define ECHECK(err) (errno == err) 71#endif 72#endif 73 74/* 75 * Attempts to connect to server, given server name. Returns transport 76 * connection object or NULL if connection fails. 77 */ 78 79#define FS_CONNECTION_RETRIES 5 80 81XtransConnInfo 82_FSConnectServer(char *server_name) 83{ 84 XtransConnInfo trans_conn = NULL; /* transport connection object */ 85 int retry, connect_stat; 86 int madeConnection = 0; 87 88 /* 89 * Open the network connection. 90 */ 91 92 for (retry = FS_CONNECTION_RETRIES; retry >= 0; retry--) 93 { 94 if ((trans_conn = _FSTransOpenCOTSClient(server_name)) == NULL) 95 { 96 break; 97 } 98 99 if ((connect_stat = _FSTransConnect(trans_conn,server_name)) < 0) 100 { 101 _FSTransClose(trans_conn); 102 103 if (connect_stat == TRANS_TRY_CONNECT_AGAIN) 104 { 105 sleep(1); 106 continue; 107 } 108 else 109 break; 110 } 111 else 112 { 113 madeConnection = 1; 114 break; 115 } 116 } 117 118 if (!madeConnection) 119 return (NULL); 120 121 122 /* 123 * set it non-blocking. This is so we can read data when blocked for 124 * writing in the library. 125 */ 126 127 _FSTransSetOption(trans_conn, TRANS_NONBLOCKING, 1); 128 129 return (trans_conn); 130} 131 132/* 133 * Disconnect from server. 134 */ 135 136void 137_FSDisconnectServer(XtransConnInfo trans_conn) 138 139{ 140 (void) _FSTransClose(trans_conn); 141} 142 143 144/* 145 * This is an OS dependent routine which: 146 * 1) returns as soon as the connection can be written on.... 147 * 2) if the connection can be read, must enqueue events and handle errors, 148 * until the connection is writable. 149 */ 150void _FSWaitForWritable(FSServer *svr) 151{ 152 fd_set r_mask; 153 fd_set w_mask; 154 int nfound; 155 156 FD_ZERO(&r_mask); 157 FD_ZERO(&w_mask); 158 159 while (1) { 160 FD_SET(svr->fd, &r_mask); 161 FD_SET(svr->fd, &w_mask); 162 163 do { 164 nfound = Select(svr->fd + 1, &r_mask, &w_mask, NULL, NULL); 165 if (nfound < 0 && !ECHECK(EINTR)) 166 (*_FSIOErrorFunction) (svr); 167 } while (nfound <= 0); 168 169 if (XFD_ANYSET(&r_mask)) { 170 char buf[BUFSIZE]; 171 BytesReadable_t pend_not_register; 172 register BytesReadable_t pend; 173 register fsEvent *ev; 174 175 /* find out how much data can be read */ 176 if (_FSTransBytesReadable(svr->trans_conn, &pend_not_register) < 0) 177 (*_FSIOErrorFunction) (svr); 178 pend = pend_not_register; 179 180 /* 181 * must read at least one fsEvent; if none is pending, then we'll 182 * just block waiting for it 183 */ 184 if (pend < SIZEOF(fsEvent)) 185 pend = SIZEOF(fsEvent); 186 187 /* but we won't read more than the max buffer size */ 188 if (pend > BUFSIZE) 189 pend = BUFSIZE; 190 191 /* round down to an integral number of FSReps */ 192 pend = (pend / SIZEOF(fsEvent)) * SIZEOF(fsEvent); 193 194 _FSRead(svr, buf, pend); 195 196 /* no space between comma and type or else macro will die */ 197 STARTITERATE(ev, fsEvent, buf, (pend > 0), 198 (pend -= SIZEOF(fsEvent))) { 199 if (ev->type == FS_Error) 200 _FSError(svr, (fsError *) ev); 201 else /* it's an event packet; enqueue it */ 202 _FSEnq(svr, ev); 203 } 204 ENDITERATE 205 } 206 if (XFD_ANYSET(&w_mask)) 207 return; 208 } 209} 210 211 212void _FSWaitForReadable(FSServer *svr) 213{ 214 fd_set r_mask; 215 int result; 216 217 FD_ZERO(&r_mask); 218 do { 219 FD_SET(svr->fd, &r_mask); 220 result = Select(svr->fd + 1, &r_mask, NULL, NULL, NULL); 221 if (result == -1 && !ECHECK(EINTR)) 222 (*_FSIOErrorFunction) (svr); 223 } while (result <= 0); 224} 225 226void _FSSendClientPrefix( 227 FSServer *svr, 228 fsConnClientPrefix *client) 229{ 230 struct iovec iovarray[5], 231 *iov = iovarray; 232 int niov = 0; 233 234#define add_to_iov(b,l) \ 235 { iov->iov_base = (b); iov->iov_len = (l); iov++, niov++; } 236 237 add_to_iov((caddr_t) client, SIZEOF(fsConnClientPrefix)); 238 239#undef add_to_iov 240 241 (void) _FSTransWritev(svr->trans_conn, iovarray, niov); 242 return; 243} 244