Add interfaces to get FDs from clients over the socket

This adds two interfaces:

    void SetReqFds(ClientPtr client, int req_fds)

	Marks the number of file descriptors expected for this
	request. Call this before any request processing so that
	any un-retrieved file descriptors will be closed
	automatically.

    int ReadFdFromClient(ClientPtr client)

	Reads the next queued file descriptor from the connection. If
	this request is not expecting any more file descriptors, or
	if there are no more file descriptors available from the
	connection, then this will return -1.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Keith Packard 2013-01-17 13:43:02 -08:00
parent 264fc3abe5
commit 9fd35daa31
3 changed files with 31 additions and 0 deletions

View File

@ -110,8 +110,16 @@ typedef struct _Client {
DeviceIntPtr clientPtr;
ClientIdPtr clientIds;
int req_fds;
} ClientRec;
static inline void
SetReqFds(ClientPtr client, int req_fds) {
if (client->req_fds != 0 && req_fds != client->req_fds)
LogMessage(X_ERROR, "Mismatching number of request fds %d != %d\n", req_fds, client->req_fds);
client->req_fds = req_fds;
}
/*
* Scheduling interface
*/

View File

@ -98,6 +98,8 @@ extern _X_EXPORT int WaitForSomething(int * /*pClientsReady */
extern _X_EXPORT int ReadRequestFromClient(ClientPtr /*client */ );
extern _X_EXPORT int ReadFdFromClient(ClientPtr client);
extern _X_EXPORT Bool InsertFakeRequest(ClientPtr /*client */ ,
char * /*data */ ,
int /*count */ );

21
os/io.c
View File

@ -259,6 +259,12 @@ ReadRequestFromClient(ClientPtr client)
oc->input = oci;
}
/* Discard any unused file descriptors */
while (client->req_fds > 0) {
int req_fd = ReadFdFromClient(client);
if (req_fd >= 0)
close(req_fd);
}
/* advance to start of next request */
oci->bufptr += oci->lenLastReq;
@ -485,6 +491,21 @@ ReadRequestFromClient(ClientPtr client)
return needed;
}
int
ReadFdFromClient(ClientPtr client)
{
int fd = -1;
if (client->req_fds > 0) {
OsCommPtr oc = (OsCommPtr) client->osPrivate;
--client->req_fds;
fd = _XSERVTransRecvFd(oc->trans_conn);
} else
LogMessage(X_ERROR, "Request asks for FD without setting req_fds\n");
return fd;
}
/*****************************************************************
* InsertFakeRequest
* Splice a consed up (possibly partial) request in as the next request.