void CloseWellKnownConnections(void) { int i; for (i = 0; i < ListenTransCount; i++) _XSERVTransClose (ListenTransConns[i]); }
void CloseWellKnownConnections(void) { int i; for (i = 0; i < ListenTransCount; i++) { if (ListenTransConns[i] != NULL) { _XSERVTransClose(ListenTransConns[i]); ListenTransConns[i] = NULL; } } ListenTransCount = 0; }
/*ARGSUSED*/ Bool EstablishNewConnections(ClientPtr clientUnused, pointer closure) { fd_set readyconnections; /* set of listeners that are ready */ int curconn; /* fd of listener that's ready */ register int newconn; /* fd of new client */ CARD32 connect_time; register int i; register ClientPtr client; register OsCommPtr oc; fd_set tmask; XFD_ANDSET (&tmask, (fd_set*)closure, &WellKnownConnections); XFD_COPYSET(&tmask, &readyconnections); if (!XFD_ANYSET(&readyconnections)) return TRUE; connect_time = GetTimeInMillis(); /* kill off stragglers */ for (i=1; i<currentMaxClients; i++) { if ((client = clients[i])) { oc = (OsCommPtr)(client->osPrivate); if ((oc && (oc->conn_time != 0) && (connect_time - oc->conn_time) >= TimeOutValue) || (client->noClientException != Success && !client->clientGone)) CloseDownClient(client); } } #ifndef WIN32 for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) { while (readyconnections.fds_bits[i]) #else for (i = 0; i < XFD_SETCOUNT(&readyconnections); i++) #endif { XtransConnInfo trans_conn, new_trans_conn; int status; #ifndef WIN32 curconn = mffs (readyconnections.fds_bits[i]) - 1; readyconnections.fds_bits[i] &= ~((fd_mask)1 << curconn); curconn += (i * (sizeof(fd_mask)*8)); #else curconn = XFD_FD(&readyconnections, i); #endif if ((trans_conn = lookup_trans_conn (curconn)) == NULL) continue; if ((new_trans_conn = _XSERVTransAccept (trans_conn, &status)) == NULL) continue; newconn = _XSERVTransGetConnectionNumber (new_trans_conn); if (newconn < lastfdesc) { int clientid; #if !defined(WIN32) clientid = ConnectionTranslation[newconn]; #else clientid = GetConnectionTranslation(newconn); #endif if(clientid && (client = clients[clientid])) CloseDownClient(client); } _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); if (!AllocNewConnection (new_trans_conn, newconn, connect_time)) { ErrorConnMax(new_trans_conn); _XSERVTransClose(new_trans_conn); } if(trans_conn->flags & TRANS_NOXAUTH) new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH; } #ifndef WIN32 } #endif return TRUE; }
int FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) { ConnectionOutputPtr oco = oc->output; int connection = oc->fd; XtransConnInfo trans_conn = oc->trans_conn; struct iovec iov[3]; static char padBuffer[3]; const char *extraBuf = __extraBuf; long written; long padsize; long notWritten; long todo; if (!oco) return 0; written = 0; padsize = padding_for_int32(extraCount); notWritten = oco->count + extraCount + padsize; if (!notWritten) return 0; todo = notWritten; while (notWritten) { long before = written; /* amount of whole thing written */ long remain = todo; /* amount to try this time, <= notWritten */ int i = 0; long len; /* You could be very general here and have "in" and "out" iovecs * and write a loop without using a macro, but what the heck. This * translates to: * * how much of this piece is new? * if more new then we are trying this time, clamp * if nothing new * then bump down amount already written, for next piece * else put new stuff in iovec, will need all of next piece * * Note that todo had better be at least 1 or else we'll end up * writing 0 iovecs. */ #define InsertIOV(pointer, length) \ len = (length) - before; \ if (len > remain) \ len = remain; \ if (len <= 0) { \ before = (-len); \ } else { \ iov[i].iov_len = len; \ iov[i].iov_base = (pointer) + before; \ i++; \ remain -= len; \ before = 0; \ } InsertIOV((char *) oco->buf, oco->count) InsertIOV((char *) extraBuf, extraCount) InsertIOV(padBuffer, padsize) errno = 0; if (trans_conn && (len = _XSERVTransWritev(trans_conn, iov, i)) >= 0) { written += len; notWritten -= len; todo = notWritten; } else if (ETEST(errno) #ifdef SUNSYSV /* check for another brain-damaged OS bug */ || (errno == 0) #endif #ifdef EMSGSIZE /* check for another brain-damaged OS bug */ || ((errno == EMSGSIZE) && (todo == 1)) #endif ) { /* If we've arrived here, then the client is stuffed to the gills and not ready to accept more. Make a note of it and buffer the rest. */ errno=0; FD_SET(connection, &ClientsWriteBlocked); AnyClientsWriteBlocked = TRUE; if (written < oco->count) { if (written > 0) { oco->count -= written; memmove((char *) oco->buf, (char *) oco->buf + written, oco->count); written = 0; } } else { written -= oco->count; oco->count = 0; } if (notWritten > oco->size) { unsigned char *obuf = NULL; if (notWritten + BUFSIZE <= INT_MAX) { obuf = realloc(oco->buf, notWritten + BUFSIZE); } if (!obuf) { _XSERVTransDisconnect(oc->trans_conn); _XSERVTransClose(oc->trans_conn); oc->trans_conn = NULL; MarkClientException(who); oco->count = 0; return -1; } oco->size = notWritten + BUFSIZE; oco->buf = obuf; } /* If the amount written extended into the padBuffer, then the difference "extraCount - written" may be less than 0 */ if ((len = extraCount - written) > 0) memmove((char *) oco->buf + oco->count, extraBuf + written, len); oco->count = notWritten; /* this will include the pad */ /* return only the amount explicitly requested */ return extraCount; } #ifdef EMSGSIZE /* check for another brain-damaged OS bug */ else if (errno == EMSGSIZE) { todo >>= 1; } #endif else { if (oc->trans_conn) {
int WriteToClient(ClientPtr who, int count, const void *__buf) { OsCommPtr oc; ConnectionOutputPtr oco; int padBytes; const char *buf = __buf; #ifdef DEBUG_COMMUNICATION Bool multicount = FALSE; #endif if (!count || !who || who == serverClient || who->clientGone) return 0; oc = who->osPrivate; oco = oc->output; #ifdef DEBUG_COMMUNICATION { char info[128]; xError *err; xGenericReply *rep; xEvent *ev; if (!who->replyBytesRemaining) { switch (buf[0]) { case X_Reply: rep = (xGenericReply *) buf; if (rep->sequenceNumber == who->sequence) { snprintf(info, 127, "Xreply: type: 0x%x data: 0x%x " "len: %i seq#: 0x%x", rep->type, rep->data1, rep->length, rep->sequenceNumber); multicount = TRUE; } break; case X_Error: err = (xError *) buf; snprintf(info, 127, "Xerror: Code: 0x%x resID: 0x%x maj: 0x%x " "min: %x", err->errorCode, err->resourceID, err->minorCode, err->majorCode); break; default: if ((buf[0] & 0x7f) == KeymapNotify) snprintf(info, 127, "KeymapNotifyEvent: %i", buf[0]); else { ev = (xEvent *) buf; snprintf(info, 127, "XEvent: type: 0x%x detail: 0x%x " "seq#: 0x%x", ev->u.u.type, ev->u.u.detail, ev->u.u.sequenceNumber); } } ErrorF("REPLY: ClientIDX: %i %s\n", who->index, info); } else multicount = TRUE; } #endif if (!oco) { if ((oco = FreeOutputs)) { FreeOutputs = oco->next; } else if (!(oco = AllocateOutputBuffer())) { if (oc->trans_conn) { _XSERVTransDisconnect(oc->trans_conn); _XSERVTransClose(oc->trans_conn); oc->trans_conn = NULL; } MarkClientException(who); return -1; } oc->output = oco; } padBytes = padding_for_int32(count); if (ReplyCallback) { ReplyInfoRec replyinfo; replyinfo.client = who; replyinfo.replyData = buf; replyinfo.dataLenBytes = count + padBytes; replyinfo.padBytes = padBytes; if (who->replyBytesRemaining) { /* still sending data of an earlier reply */ who->replyBytesRemaining -= count + padBytes; replyinfo.startOfReply = FALSE; replyinfo.bytesRemaining = who->replyBytesRemaining; CallCallbacks((&ReplyCallback), (void *) &replyinfo); } else if (who->clientState == ClientStateRunning && buf[0] == X_Reply) { /* start of new reply */ CARD32 replylen; unsigned long bytesleft; replylen = ((const xGenericReply *) buf)->length; if (who->swapped) swapl(&replylen); bytesleft = (replylen * 4) + SIZEOF(xReply) - count - padBytes; replyinfo.startOfReply = TRUE; replyinfo.bytesRemaining = who->replyBytesRemaining = bytesleft; CallCallbacks((&ReplyCallback), (void *) &replyinfo); } } #ifdef DEBUG_COMMUNICATION else if (multicount) { if (who->replyBytesRemaining) { who->replyBytesRemaining -= (count + padBytes); } else { CARD32 replylen; replylen = ((xGenericReply *) buf)->length; who->replyBytesRemaining = (replylen * 4) + SIZEOF(xReply) - count - padBytes; } } #endif if (oco->count == 0 || oco->count + count + padBytes > oco->size) { FD_CLR(oc->fd, &OutputPending); if (!XFD_ANYSET(&OutputPending)) { CriticalOutputPending = FALSE; NewOutputPending = FALSE; } if (FlushCallback) CallCallbacks(&FlushCallback, NULL); return FlushClient(who, oc, buf, count); } NewOutputPending = TRUE; FD_SET(oc->fd, &OutputPending); memmove((char *) oco->buf + oco->count, buf, count); oco->count += count; if (padBytes) { memset(oco->buf + oco->count, '\0', padBytes); oco->count += padBytes; } return count; }