📄 connection.c
字号:
int whichbyte = 1;#ifndef AMOEBA struct timeval waittime; fd_set mask; /* if these seems like a lot of trouble to go to, it probably is */ waittime.tv_sec = BOTIMEOUT / MILLI_PER_SECOND; waittime.tv_usec = (BOTIMEOUT % MILLI_PER_SECOND) * (1000000 / MILLI_PER_SECOND); FD_ZERO(&mask); FD_SET(fd, &mask); (void)Select(fd + 1, &mask, NULL, NULL, &waittime);#endif /* try to read the byte-order of the connection */ (void)_XSERVTransRead(trans_conn, &byteOrder, 1); if ((byteOrder == 'l') || (byteOrder == 'B')) { csp.success = xFalse; csp.lengthReason = sizeof(NOROOM) - 1; csp.length = (sizeof(NOROOM) + 2) >> 2; csp.majorVersion = X_PROTOCOL; csp.minorVersion = X_PROTOCOL_REVISION; if (((*(char *) &whichbyte) && (byteOrder == 'B')) || (!(*(char *) &whichbyte) && (byteOrder == 'l'))) { swaps(&csp.majorVersion, whichbyte); swaps(&csp.minorVersion, whichbyte); swaps(&csp.length, whichbyte); } iov[0].iov_len = sz_xConnSetupPrefix; iov[0].iov_base = (char *) &csp; iov[1].iov_len = csp.lengthReason; iov[1].iov_base = NOROOM; iov[2].iov_len = (4 - (csp.lengthReason & 3)) & 3; iov[2].iov_base = pad; (void)_XSERVTransWritev(trans_conn, iov, 3); }}/************ * CloseDownFileDescriptor: * Remove this file descriptor and it's I/O buffers, etc. ************/#ifdef LBXvoidCloseDownFileDescriptor(client) ClientPtr client;#elsestatic voidCloseDownFileDescriptor(oc) register OsCommPtr oc;#endif{#ifdef LBX register OsCommPtr oc = (OsCommPtr) client->osPrivate;#endif int connection = oc->fd; if (oc->trans_conn) { _XSERVTransDisconnect(oc->trans_conn); _XSERVTransClose(oc->trans_conn); }#ifdef LBX ConnectionTranslation[connection] = 0;#else FreeOsBuffers(oc);#endif FD_CLR(connection, &AllSockets); FD_CLR(connection, &AllClients); FD_CLR(connection, &ClientsWithInput); FD_CLR(connection, &GrabImperviousClients); if (GrabInProgress) { FD_CLR(connection, &SavedAllSockets); FD_CLR(connection, &SavedAllClients); FD_CLR(connection, &SavedClientsWithInput); } FD_CLR(connection, &ClientsWriteBlocked); if (!XFD_ANYSET(&ClientsWriteBlocked)) AnyClientsWriteBlocked = FALSE; FD_CLR(connection, &OutputPending);#ifndef LBX xfree(oc);#endif}/***************** * CheckConections * Some connection has died, go find which one and shut it down * The file descriptor has been closed, but is still in AllClients. * If would truly be wonderful if select() would put the bogus * file descriptors in the exception mask, but nooooo. So we have * to check each and every socket individually. *****************/voidCheckConnections(){#ifndef WIN32 fd_mask mask;#endif fd_set tmask; register int curclient, curoff; int i; struct timeval notime; int r;#ifdef WIN32 fd_set savedAllClients;#endif#ifndef AMOEBA notime.tv_sec = 0; notime.tv_usec = 0;#ifndef WIN32 for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++) { mask = AllClients.fds_bits[i]; while (mask) { curoff = ffsl(mask) - 1; curclient = curoff + (8 * sizeof(fd_mask) * i); FD_ZERO(&tmask); FD_SET(curclient, &tmask); r = Select (curclient + 1, &tmask, NULL, NULL, ¬ime); if (r < 0) CloseDownClient(clients[ConnectionTranslation[curclient]]); mask &= ~(((fd_mask)1) << curoff); } } #else XFD_COPYSET(&AllClients, &savedAllClients); for (i = 0; i < XFD_SETCOUNT(&savedAllClients); i++) { curclient = XFD_FD(&savedAllClients, i); FD_ZERO(&tmask); FD_SET(curclient, &tmask); r = Select (curclient + 1, &tmask, NULL, NULL, ¬ime); if (r < 0) CloseDownClient(clients[ConnectionTranslation[curclient]]); } #endif#endif}/***************** * CloseDownConnection * Delete client from AllClients and free resources *****************/voidCloseDownConnection(client) ClientPtr client;{ OsCommPtr oc = (OsCommPtr)client->osPrivate; if (oc->output && oc->output->count) FlushClient(client, oc, (char *)NULL, 0);#ifdef XDMCP XdmcpCloseDisplay(oc->fd);#endif#ifndef LBX CloseDownFileDescriptor(oc);#else (*oc->Close) (client); FreeOsBuffers(oc); xfree(oc);#endif client->osPrivate = (pointer)NULL; if (auditTrailLevel > 1) AuditF("client %d disconnected\n", client->index);}AddEnabledDevice(fd) int fd;{ FD_SET(fd, &EnabledDevices); FD_SET(fd, &AllSockets);}RemoveEnabledDevice(fd) int fd;{ FD_CLR(fd, &EnabledDevices); FD_CLR(fd, &AllSockets);}/***************** * OnlyListenToOneClient: * Only accept requests from one client. Continue to handle new * connections, but don't take any protocol requests from the new * ones. Note that if GrabInProgress is set, EstablishNewConnections * needs to put new clients into SavedAllSockets and SavedAllClients. * Note also that there is no timeout for this in the protocol. * This routine is "undone" by ListenToAllClients() *****************/OnlyListenToOneClient(client) ClientPtr client;{ OsCommPtr oc = (OsCommPtr)client->osPrivate; int connection = oc->fd; if (! GrabInProgress) { XFD_COPYSET(&ClientsWithInput, &SavedClientsWithInput); XFD_ANDSET(&ClientsWithInput, &ClientsWithInput, &GrabImperviousClients); if (FD_ISSET(connection, &SavedClientsWithInput)) { FD_CLR(connection, &SavedClientsWithInput); FD_SET(connection, &ClientsWithInput); } XFD_UNSET(&SavedClientsWithInput, &GrabImperviousClients); XFD_COPYSET(&AllSockets, &SavedAllSockets); XFD_COPYSET(&AllClients, &SavedAllClients); XFD_UNSET(&AllSockets, &AllClients); XFD_ANDSET(&AllClients, &AllClients, &GrabImperviousClients); FD_SET(connection, &AllClients); XFD_ORSET(&AllSockets, &AllSockets, &AllClients); GrabInProgress = client->index; }}/**************** * ListenToAllClients: * Undoes OnlyListentToOneClient() ****************/ListenToAllClients(){ if (GrabInProgress) { XFD_ORSET(&AllSockets, &AllSockets, &SavedAllSockets); XFD_ORSET(&AllClients, &AllClients, &SavedAllClients); XFD_ORSET(&ClientsWithInput, &ClientsWithInput, &SavedClientsWithInput); GrabInProgress = 0; } }/**************** * IgnoreClient * Removes one client from input masks. * Must have cooresponding call to AttendClient. ****************/IgnoreClient (client) ClientPtr client;{ OsCommPtr oc = (OsCommPtr)client->osPrivate; int connection = oc->fd;#ifdef LBX LbxClientPtr lbxClient = LbxClient(client);#endif isItTimeToYield = TRUE;#ifdef LBX if (lbxClient) { lbxClient->ignored = TRUE; return; }#endif if (!GrabInProgress || FD_ISSET(connection, &AllClients)) { if (FD_ISSET (connection, &ClientsWithInput)) FD_SET(connection, &IgnoredClientsWithInput); else FD_CLR(connection, &IgnoredClientsWithInput); FD_CLR(connection, &ClientsWithInput); FD_CLR(connection, &AllSockets); FD_CLR(connection, &AllClients); FD_CLR(connection, &LastSelectMask); } else { if (FD_ISSET (connection, &SavedClientsWithInput)) FD_SET(connection, &IgnoredClientsWithInput); else FD_CLR(connection, &IgnoredClientsWithInput); FD_CLR(connection, &SavedClientsWithInput); FD_CLR(connection, &SavedAllSockets); FD_CLR(connection, &SavedAllClients); }}/**************** * AttendClient * Adds one client back into the input masks. ****************/AttendClient (client) ClientPtr client;{ OsCommPtr oc = (OsCommPtr)client->osPrivate; int connection = oc->fd;#ifdef LBX LbxClientPtr lbxClient = LbxClient(client); if (lbxClient) { lbxClient->ignored = FALSE; return; }#endif if (!GrabInProgress || GrabInProgress == client->index || FD_ISSET(connection, &GrabImperviousClients)) { FD_SET(connection, &AllClients); FD_SET(connection, &AllSockets); FD_SET(connection, &LastSelectMask); if (FD_ISSET (connection, &IgnoredClientsWithInput)) FD_SET(connection, &ClientsWithInput); } else { FD_SET(connection, &SavedAllClients); FD_SET(connection, &SavedAllSockets); if (FD_ISSET(connection, &IgnoredClientsWithInput)) FD_SET(connection, &SavedClientsWithInput); }}/* make client impervious to grabs; assume only executing client calls this */MakeClientGrabImpervious(client) ClientPtr client;{ OsCommPtr oc = (OsCommPtr)client->osPrivate; int connection = oc->fd; FD_SET(connection, &GrabImperviousClients); if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; grabinfo.client = client; grabinfo.grabstate = CLIENT_IMPERVIOUS; CallCallbacks(&ServerGrabCallback, &grabinfo); }}/* make client pervious to grabs; assume only executing client calls this */MakeClientGrabPervious(client) ClientPtr client;{ OsCommPtr oc = (OsCommPtr)client->osPrivate; int connection = oc->fd; FD_CLR(connection, &GrabImperviousClients); if (GrabInProgress && (GrabInProgress != client->index)) { if (FD_ISSET(connection, &ClientsWithInput)) { FD_SET(connection, &SavedClientsWithInput); FD_CLR(connection, &ClientsWithInput); } FD_CLR(connection, &AllSockets); FD_CLR(connection, &AllClients); isItTimeToYield = TRUE; } if (ServerGrabCallback) { ServerGrabInfoRec grabinfo; grabinfo.client = client; grabinfo.grabstate = CLIENT_PERVIOUS; CallCallbacks(&ServerGrabCallback, &grabinfo); }}#ifdef AIXV3static fd_set pendingActiveClients;static BOOL reallyGrabbed;/***************** DontListenToAnybody:* Don't listen to requests from any clients. Continue to handle new* connections, but don't take any protocol requests from anybody.* We have to take care if there is already a grab in progress, though.* Undone by PayAttentionToClientsAgain. We also have to be careful* not to accept any more input from the currently dispatched client.* we do this be telling dispatch it is time to yield.* We call this when the server loses access to the glass* (user hot-keys away). This looks like a grab by the * server itself, but gets a little tricky if there is already* a grab in progress.******************/voidDontListenToAnybody(){ if (!GrabInProgress) { XFD_COPYSET(&ClientsWithInput, &SavedClientsWithInput); XFD_COPYSET(&AllSockets, &SavedAllSockets); XFD_COPYSET(&AllClients, &SavedAllClients); GrabInProgress = TRUE; reallyGrabbed = FALSE; } else { XFD_COPYSET(&AllClients, &pendingActiveClients); reallyGrabbed = TRUE; } FD_ZERO(&ClientsWithInput); XFD_UNSET(&AllSockets, &AllClients); FD_ZERO(&AllClients); isItTimeToYield = TRUE;}voidPayAttentionToClientsAgain(){ if (reallyGrabbed) { XFD_ORSET(&AllSockets, &AllSockets, &pendingActiveClients); XFD_ORSET(&AllClients, &AllClients, &pendingActiveClients); } else { ListenToAllClients(); } reallyGrabbed = FALSE;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -