void CloseSockets(void) { int i; for (i = 0; i < ListenTransCount; i++) _FontTransClose (ListenTransConns[i]); }
int FlushClient( ClientPtr client, OsCommPtr oc, char *extraBuf, int extraCount, int padsize) { ConnectionOutputPtr oco = oc->output; int fd = oc->fd; struct iovec iov[3]; char padBuffer[3]; long written; long notWritten; long todo; if (!oco) return 0; written = 0; notWritten = oco->count + extraCount + padsize; todo = notWritten; while (notWritten) { long before = written; long remain = todo; 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(extraBuf, extraCount); InsertIOV(padBuffer, padsize); errno = 0; if (oc->trans_conn && (len = _FontTransWritev(oc->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 ) { FD_SET(fd, &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; } /* grow buffer if necessary */ if (notWritten > oco->size) { unsigned char *obuf; obuf = (unsigned char *) fsrealloc(oco->buf, notWritten + OutputBufferSize); if (!obuf) { if (oc->trans_conn) _FontTransClose(oc->trans_conn); oc->trans_conn = NULL; MarkClientException(client); oco->count = 0; return -1; } oco->size = notWritten + OutputBufferSize; oco->buf = obuf; } if ((len = extraCount - written) > 0) { memmove( (char *) oco->buf + oco->count, extraBuf + written, len); } oco->count = notWritten; return extraCount; } #ifdef EMSGSIZE /* check for another brain-damaged OS bug */ else if (errno == EMSGSIZE) { todo >>= 1; } #endif else { if (oc->trans_conn)
/* * accepts new connections */ void MakeNewConnections(void) { fd_mask readyconnections; int curconn; int newconn; long connect_time; int i; ClientPtr client; OsCommPtr oc; fd_set tmask; XFD_ANDSET (&tmask, &LastSelectMask, &WellKnownConnections); readyconnections = tmask.fds_bits[0]; if (!readyconnections) return; connect_time = GetTimeInMillis(); /* kill off stragglers */ for (i = MINCLIENT; i < currentMaxClients; i++) { if ((client = clients[i]) != NullClient) { oc = (OsCommPtr) client->osPrivate; if ((oc && (oc->conn_time != 0) && (connect_time - oc->conn_time) >= TimeOutValue) || ((client->noClientException != FSSuccess) && (client->clientGone != CLIENT_GONE))) CloseDownClient(client); } } while (readyconnections) { XtransConnInfo trans_conn, new_trans_conn; int status; curconn = ffs(readyconnections) - 1; readyconnections &= ~(1 << curconn); if ((trans_conn = lookup_trans_conn (curconn)) == NULL) continue; if ((new_trans_conn = _FontTransAccept (trans_conn, &status)) == NULL) continue; newconn = _FontTransGetConnectionNumber (new_trans_conn); _FontTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); oc = (OsCommPtr) fsalloc(sizeof(OsCommRec)); if (!oc) { fsfree(oc); error_conn_max(new_trans_conn); _FontTransClose(new_trans_conn); continue; } FD_SET(newconn, &AllClients); FD_SET(newconn, &AllSockets); oc->fd = newconn; oc->trans_conn = new_trans_conn; oc->input = (ConnectionInputPtr) NULL; oc->output = (ConnectionOutputPtr) NULL; oc->conn_time = connect_time; if ((newconn < lastfdesc) && (client = NextAvailableClient((pointer) oc))) { ConnectionTranslation[newconn] = client->index; } else { error_conn_max(new_trans_conn); close_fd(oc); } } }