From 074646707400ff659909fff1f059f58f44493a38 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 15 Mar 2017 13:27:12 +0000 Subject: os/xdmcp: Remove dead 'restart' code Completing the below X.org commit: commit a3a40291330bad10401fe2bcdbc097ce742b026a Author: Keith Packard Date: Mon Sep 21 07:16:16 2015 +0100 os/xdmcp: Remove dead 'restart' code The X server used to wait for the user to hit a key or move the mouse before restarting the session after a keepalive failure. This, presumably, was to avoid having the X server continuously spew XDMCP protocol on the network while the XDM server was dead. Switching into this state was removed from the server some time before XFree86 4.3.99.16, so the remaining bits of code have been dead for over a decade, and no-one ever noticed. Reviewed-by: Adam Jackson Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/xdmcp.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/nx-X11/programs/Xserver/os/xdmcp.c b/nx-X11/programs/Xserver/os/xdmcp.c index c4b71f6ec..c1aa57e95 100644 --- a/nx-X11/programs/Xserver/os/xdmcp.c +++ b/nx-X11/programs/Xserver/os/xdmcp.c @@ -205,8 +205,6 @@ extern void XdmcpDeadSession(char * /*reason*/); static void timeout(void); -static void restart(void); - static void XdmcpBlockHandler( void * /*data*/, struct timeval ** /*wt*/, @@ -959,14 +957,6 @@ timeout(void) send_packet(); } -static void -restart(void) -{ - state = XDM_INIT_STATE; - timeOutRtx = 0; - send_packet(); -} - int XdmcpCheckAuthentication ( ARRAY8Ptr Name, -- cgit v1.2.3 From 645b757df77b2f85028e16c2e303b288fe2474af Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Feb 2017 13:18:04 +0000 Subject: os: Immediately queue initial WriteToClient Backported from X.org: commit 9bf46610a9d20962854016032de4567974e87957 Author: Chris Wilson Date: Fri Jun 21 22:58:31 2013 +0100 os: Immediately queue initial WriteToClient If we immediately put the WriteToClient() buffer into the socket's write queue, not only do we benefit from sending the response back to client earlier, but we also avoid the overhead of copying the data into our own staging buffer and causing extra work in the next select(). The write is effectively free as typically we may only send one reply per client per select() call, so the cost of the FlushClient() is the same. shmget10: 26400 -> 110000 getimage10: 25000 -> 108000 shmget500: 3160 -> 13500 getimage500: 1000 -> 1010 The knock-on effect is that on a mostly idle composited desktop, the CPU overhead is dominated by the memmove in WriteToClient, which is in turn eliminated by this patch. Reviewed-by: Adam Jackson Signed-off-by: Chris Wilson Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index 92a3f0476..a02d7fb0c 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -958,7 +958,7 @@ WriteToClient (ClientPtr who, int count, const void *__buf) } } #endif - if (oco->count + count + padBytes > oco->size) + if (oco->count == 0 || oco->count + count + padBytes > oco->size) { FD_CLR(oc->fd, &OutputPending); if(!XFD_ANYSET(&OutputPending)) { -- cgit v1.2.3 From af7c3750070dfad2ebd2d615f2c3fecda7e58053 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 14 Feb 2017 14:59:51 +0000 Subject: Xserver/os/io.c: Bail out early from FlushClient if nothing needs to be written. Found in X.org commit: commit d5bf6f95f31037bd49b11348b500c3c13b7e0c99 Author: Keith Packard Date: Thu Oct 4 14:42:37 2012 -0700 Fix FlushClient to write extraBuf when provided (regression fix) In commit: commit 092c57ab173c8b71056f6feb3b9d04d063a46579 Author: Adam Jackson Date: Fri Jun 17 14:03:01 2011 -0400 os: Hide the Connection{In,Out}put implementation details Reviewed-by: Daniel Stone Signed-off-by: Adam Jackson the check for an empty output buffer was moved from one calling location into the FlushClient implementation itself. However, this neglected the possibility that additional data, in the form of 'extraBuf' would be passed to FlushClient from other code paths. If the output buffer happened to be empty at that time, the extra data would never be written to the client. This is fixed by checking the total data to be written, which includes both pending and extra data, instead of just the pending data. Signed-off-by: Keith Packard Reviewed-by: Julien Cristau Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/io.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index a02d7fb0c..23f436b84 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -1004,6 +1004,10 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) written = 0; padsize = padlength[extraCount & 3]; notWritten = oco->count + extraCount + padsize; + + if (!notWritten) + return 0; + todo = notWritten; while (notWritten) { long before = written; /* amount of whole thing written */ -- cgit v1.2.3 From 65b6a62bc726b5e4f4833ed1e27733e22fabcfa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 15 Feb 2017 08:13:57 +0000 Subject: dix: Pass ClientPtr to FlushCallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backported X.org commits: commit b380f3ac51f40ffefcde7d3db5c4c149f274246d Author: Michel Dänzer Date: Tue Aug 2 17:53:01 2016 +0900 dix: Pass ClientPtr to FlushCallback This change has two effects: 1. Only calls FlushCallbacks when we're actually flushing data to a client. The unnecessary FlushCallback calls could cause significant performance degradation with compositing, which is significantly reduced even without any driver changes. 2. By passing the ClientPtr to FlushCallbacks, drivers can completely eliminate unnecessary flushing of GPU commands by keeping track of whether we're flushing any XDamageNotify events to the client for which the corresponding rendering commands haven't been flushed to the GPU yet. Reviewed-by: Adam Jackson Signed-off-by: Michel Dänzer commit c65f610e12f9df168d5639534ed3c2bd40afffc8 Author: Kristian Høgsberg Date: Thu Jul 29 18:52:35 2010 -0400 Always call the flush callback chain when we flush client buffers We were missing the callback in a couple of places. Drivers may use the flush callback to submit batched up rendering before events (for example, damage events) are sent out, to ensure that the rendering has been queued when the client receives the event. Signed-off-by: Kristian Høgsberg Reviewed-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/connection.c | 3 +++ nx-X11/programs/Xserver/os/io.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 966fe208d..74bb13404 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -987,6 +987,9 @@ CloseDownConnection(ClientPtr client) { OsCommPtr oc = (OsCommPtr)client->osPrivate; + if (FlushCallback) + CallCallbacks(&FlushCallback, client); + if (oc->output && oc->output->count) FlushClient(client, oc, (char *)NULL, 0); #ifdef XDMCP diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index 23f436b84..f4da96518 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -755,9 +755,6 @@ FlushAllOutput(void) fd_set newOutputPending; #endif - if (FlushCallback) - CallCallbacks(&FlushCallback, NULL); - if (!newoutput) return; @@ -1008,6 +1005,9 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) if (!notWritten) return 0; + if (FlushCallback) + CallCallbacks(&FlushCallback, who); + todo = notWritten; while (notWritten) { long before = written; /* amount of whole thing written */ -- cgit v1.2.3 From cbc2d300b984d7ebc789deac0642104f223c2920 Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Tue, 14 Feb 2017 15:19:18 +0000 Subject: Fix overflow of ConnectionOutput->size and ->count commit 4b0d0df34f10a88c10cb23dd50087b59f5c4fece Author: Peter Harris Date: Mon Nov 17 14:31:24 2014 -0500 Fix overflow of ConnectionOutput->size and ->count When (long) is larger than (int), and when realloc succeeds with sizes larger than INT_MAX, ConnectionOutput->size and ConnectionOutput->count overflow and become negative. When ConnectionOutput->count is negative, InsertIOV does not actually insert an IOV, and FlushClient goes into an infinite loop of writev(fd, iov, 0) [an empty list]. Avoid this situation by killing the client when it has more than INT_MAX unread bytes of data. Signed-off-by: Peter Harris Reviewed-by: Keith Packard Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/io.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index f4da96518..4dc1e7a34 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -1087,10 +1087,11 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) if (notWritten > oco->size) { - unsigned char *obuf; + unsigned char *obuf = NULL; - obuf = (unsigned char *)realloc(oco->buf, - notWritten + BUFSIZE); + if (notWritten + BUFSIZE <= INT_MAX) { + obuf = realloc(oco->buf, notWritten + BUFSIZE); + } if (!obuf) { _XSERVTransDisconnect(oc->trans_conn); -- cgit v1.2.3 From 2ecd2a006866bd7053536c04b195319a548c6ca2 Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Tue, 14 Feb 2017 15:47:10 +0000 Subject: os: Return BadLength instead of disconnecting BigReq clients (#4565) Backported from X.org: commit 67c66606c760c263d7a4c2d1bba43ed6225a4e7c Author: Robert Morell Date: Thu May 9 13:09:02 2013 -0700 os: Reset input buffer's 'ignoreBytes' field If a client sends a request larger than maxBigRequestSize, the server is supposed to ignore it. Before commit cf88363d, the server would simply disconnect the client. After that commit, it attempts to gracefully ignore the request by remembering how long the client specified the request to be, and ignoring that many bytes. However, if a client sends a BigReq header with a large size and disconnects before actually sending the rest of the specified request, the server will reuse the ConnectionInput buffer without resetting the ignoreBytes field. This makes the server ignore new X clients' requests. This fixes that behavior by resetting the ignoreBytes field when putting the ConnectionInput buffer back on the FreeInputs list. Signed-off-by: Robert Morell Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer commit c80c41767eb101e9dbd8393d8cca7764b4e248a4 Author: Aaron Plattner Date: Mon Oct 25 22:01:32 2010 -0700 os: Fix BigReq ignoring when another request is pending Commit cf88363db0ebb42df7cc286b85d30d7898aea840 fixed the handling of BigReq requests that are way too large and handles the case where the read() syscall returns a short read. However, it neglected to handle the case where it returns a long read, which happens when the client has another request in the queue after the bogus large one. Handle the long read case by subtracting the smaller of 'needed' and 'gotnow' from oci->ignoreBytes. If needed < gotnow, simply subtract the two, leaving gotnow equal to the number of extra bytes read. Since the code immediately following the (oci->ignoreBytes > 0) block tries to handle the next request, advance oci->bufptr immediately instead of setting oci->lenLastReq and letting the next call to ReadRequestFromClient do it. Fixes the XTS pChangeKeyboardMapping-3 test. CASES TESTS PASS UNSUP UNTST NOTIU WARN FIP FAIL UNRES UNIN ABORT -Xproto 122 389 367 2 19 0 0 0 1 0 0 0 +Xproto 122 389 368 2 19 0 0 0 0 0 0 0 Signed-off-by: Aaron Plattner Reviewed-by: Adam Jackson Signed-off-by: Keith Packard commit cf88363db0ebb42df7cc286b85d30d7898aea840 Author: Aaron Plattner Date: Fri Aug 27 10:20:29 2010 -0700 os: Return BadLength instead of disconnecting BigReq clients (#4565) If a client sends a big request that's too big (i.e. bigger than maxBigRequestSize << 2 bytes), the server just disconnects it. This makes the client receive SIGPIPE the next time it tries to send something. The X Test Suite sends requests that are too big when the test specifies the TOO_LONG test type. When the client receives SIGPIPE, XTS marks it as UNRESOLVED, which counts as a failure. Instead, remember how long the request is supposed to be and then return that size. Dispatch() checks the length and sends BadLength to the client. Then, whenever oci->ignoreBytes is nonzero, ignore the data read instead of trying to process it as a request. Signed-off-by: Aaron Plattner Reviewed-by: Keith Packard Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/io.c | 43 +++++++++++++++++++++++++++++++++++--- nx-X11/programs/Xserver/os/osdep.h | 1 + 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index 4dc1e7a34..78f450b63 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -252,7 +252,14 @@ ReadRequestFromClient(ClientPtr client) move_header = FALSE; #endif gotnow = oci->bufcnt + oci->buffer - oci->bufptr; - if (gotnow < sizeof(xReq)) + + if (oci->ignoreBytes > 0) { + if (oci->ignoreBytes > oci->size) + needed = oci->size; + else + needed = oci->ignoreBytes; + } + else if (gotnow < sizeof(xReq)) { /* We don't have an entire xReq yet. Can't tell how big * the request will be until we get the whole xReq. @@ -297,8 +304,13 @@ ReadRequestFromClient(ClientPtr client) if (needed > MAXBUFSIZE) { /* request is too big for us to handle */ - YieldControlDeath(); - return -1; + /* + * Mark the rest of it as needing to be ignored, and then return + * the full size. Dispatch() will turn it into a BadLength error. + */ + oci->ignoreBytes = needed - gotnow; + oci->lenLastReq = gotnow; + return needed; } if ((gotnow == 0) || ((oci->bufptr - oci->buffer + needed) > oci->size)) @@ -405,6 +417,29 @@ ReadRequestFromClient(ClientPtr client) #endif needed = sizeof(xReq); } + + /* If there are bytes to ignore, ignore them now. */ + + if (oci->ignoreBytes > 0) { + assert(needed == oci->ignoreBytes || needed == oci->size); + oci->ignoreBytes -= gotnow; + needed = gotnow = 0; + /* + * The _XSERVTransRead call above may return more or fewer bytes than we + * want to ignore. Ignore the smaller of the two sizes. + */ + if (gotnow < needed) { + oci->ignoreBytes -= gotnow; + oci->bufptr += gotnow; + gotnow = 0; + } else { + oci->ignoreBytes -= needed; + oci->bufptr += needed; + gotnow -= needed; + } + needed = 0; + } + oci->lenLastReq = needed; /* @@ -1178,6 +1213,7 @@ AllocateInputBuffer(void) oci->bufptr = oci->buffer; oci->bufcnt = 0; oci->lenLastReq = 0; + oci->ignoreBytes = 0; return oci; } @@ -1222,6 +1258,7 @@ FreeOsBuffers(OsCommPtr oc) oci->bufptr = oci->buffer; oci->bufcnt = 0; oci->lenLastReq = 0; + oci->ignoreBytes = 0; } } if ((oco = oc->output)) diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h index 6ac9d860e..dc66649dc 100644 --- a/nx-X11/programs/Xserver/os/osdep.h +++ b/nx-X11/programs/Xserver/os/osdep.h @@ -129,6 +129,7 @@ typedef struct _connectionInput { int bufcnt; /* count of bytes in buffer */ int lenLastReq; int size; + unsigned int ignoreBytes; /* bytes to ignore before the next request */ } ConnectionInput, *ConnectionInputPtr; typedef struct _connectionOutput { -- cgit v1.2.3 From f9123570dbe81fdea4e38e7be9775cf926ed1eb3 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Tue, 14 Feb 2017 18:01:17 +0000 Subject: Set padding bytes to 0 in WriteToClient commit bed610fcae41ddfe21fa9acde599b17d1d15f5d1 Author: Alan Coopersmith Date: Mon Jul 9 19:12:44 2012 -0700 Set padding bytes to 0 in WriteToClient Clear them out when needed instead of leaving whatever values were present in previously sent messages. Signed-off-by: Alan Coopersmith Reviewed-by: Keith Packard Tested-by: Daniel Stone Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/io.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index 78f450b63..075eb677c 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -1003,7 +1003,11 @@ WriteToClient (ClientPtr who, int count, const void *__buf) NewOutputPending = TRUE; FD_SET(oc->fd, &OutputPending); memmove((char *)oco->buf + oco->count, buf, count); - oco->count += count + padBytes; + oco->count += count; + if (padBytes) { + memset(oco->buf + oco->count, '\0', padBytes); + oco->count += padBytes; + } return(count); } -- cgit v1.2.3 From eac0a8fade92e47a8fdbcceb2821e5f9bbf0063f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 15 Feb 2017 09:41:36 +0100 Subject: Don't crash on unconfigured interfaces. (X.org bug #5218, Andrei Barbu) commit 9d62d1e6903ccc095f784279a699b3f40a8f0cf8 Author: Adam Jackson Date: Sat Jan 7 00:45:17 2006 +0000 Bug #5218: Don't crash on unconfigured interfaces. (Andrei Barbu) Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/access.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c index d3a18efbe..8236a08df 100644 --- a/nx-X11/programs/Xserver/os/access.c +++ b/nx-X11/programs/Xserver/os/access.c @@ -893,6 +893,8 @@ DefineSelf (int fd) return; } for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) { + if (!ifr->ifa_addr) + continue; len = sizeof(*(ifr->ifa_addr)); family = ConvertAddr(ifr->ifa_addr, &len, (void **)&addr); if (family == -1 || family == FamilyLocal) -- cgit v1.2.3 From 7177caa702b0a914d5450767a0e632bcb56d33f8 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 15 Feb 2017 10:27:43 +0100 Subject: Xserver/os/Imakefile: Introduce the NULL variable and line-wrap various variable definitions for the sake of better readability. --- nx-X11/programs/Xserver/os/Imakefile | 123 ++++++++++++++++++++++++++--------- 1 file changed, 91 insertions(+), 32 deletions(-) diff --git a/nx-X11/programs/Xserver/os/Imakefile b/nx-X11/programs/Xserver/os/Imakefile index 8b260fa32..c2e1e8699 100644 --- a/nx-X11/programs/Xserver/os/Imakefile +++ b/nx-X11/programs/Xserver/os/Imakefile @@ -25,6 +25,8 @@ #include +NULL = + /* * If you have any extra files to be put into the library, define them here. */ @@ -33,17 +35,18 @@ NX_INCLUDES = -I../../../../nxcomp -NX_DEFINES = -DNX_TRANS_SOCKET \ - -DNX_TRANS_AUTH \ - -DNX_TRANS_FOPEN \ - -DNX_TRANS_SLEEP \ - -DNX_TRANS_EXIT \ - -DNX_TRANS_WAKEUP=1000 +NX_DEFINES = -DNX_TRANS_SOCKET \ + -DNX_TRANS_AUTH \ + -DNX_TRANS_FOPEN \ + -DNX_TRANS_SLEEP \ + -DNX_TRANS_EXIT \ + -DNX_TRANS_WAKEUP=1000 \ + $(NULL) -# -DNX_TRANS_WARN \ -# -DNX_TRANS_INFO \ -# -DNX_TRANS_TEST \ -# -DNX_TRANS_DEBUG \ +# -DNX_TRANS_WARN \ +# -DNX_TRANS_INFO \ +# -DNX_TRANS_TEST \ +# -DNX_TRANS_DEBUG \ #endif @@ -121,16 +124,51 @@ TMEMCMP_OBJS = timingsafe_memcmp.o #endif BOOTSTRAPCFLAGS = - SRCS = WaitFor.c access.c connection.c io.c $(COLOR_SRCS) \ - osinit.c utils.c log.c auth.c mitauth.c secauth.c \ - $(XDMAUTHSRCS) $(RPCSRCS) xdmcp.c OtherSources \ - xstrans.c $(SNPRINTF_SRCS) $(STRLCAT_SRCS) \ - $(REALLOCARRAY_SRCS) xprintf.c $(TMEMCMP_SRCS) - OBJS = WaitFor.o access.o connection.o io.o $(COLOR_OBJS) \ - osinit.o utils.o log.o auth.o mitauth.o secauth.o \ - $(XDMAUTHOBJS) $(RPCOBJS) xdmcp.o OtherObjects \ - xstrans.o $(SNPRINTF_OBJS) $(STRLCAT_OBJS) \ - $(REALLOCARRAY_OBJS) xprintf.o $(TMEMCMP_OBJS) + SRCS = WaitFor.c \ + access.c \ + connection.c \ + io.c \ + $(COLOR_SRCS) \ + osinit.c \ + utils.c \ + log.c \ + auth.c \ + mitauth.c \ + secauth.c \ + $(XDMAUTHSRCS) \ + $(RPCSRCS) \ + xdmcp.c \ + OtherSources \ + xstrans.c \ + $(SNPRINTF_SRCS) \ + $(STRLCAT_SRCS) \ + $(REALLOCARRAY_SRCS) \ + xprintf.c \ + $(TMEMCMP_SRCS) \ + $(NULL) + + OBJS = WaitFor.o \ + access.o \ + connection.o \ + io.o \ + $(COLOR_OBJS) \ + osinit.o \ + utils.o \ + log.o \ + auth.o \ + mitauth.o \ + secauth.o \ + $(XDMAUTHOBJS) \ + $(RPCOBJS) \ + xdmcp.o \ + OtherObjects \ + xstrans.o \ + $(SNPRINTF_OBJS) \ + $(STRLCAT_OBJS) \ + $(REALLOCARRAY_OBJS) \ + xprintf.o \ + $(TMEMCMP_OBJS) \ + $(NULL) #if UseMemLeak MEM_DEFINES = -DMEMBUG @@ -143,18 +181,39 @@ BOOTSTRAPCFLAGS = #endif XTRANS_DEFINES = -DXTRANS_SEND_FDS=0 - DEFINES = $(CONNECTION_FLAGS) $(MEM_DEFINES) \ - $(XDMAUTHDEFS) $(RPCDEFS) $(SIGNAL_DEFINES) $(OS_DEFINES) \ - $(GETPEER_DEFINES) \ - $(RANDOM_DEFINES) $(BUGMSG) $(XTRANS_FAILDEFINES) \ - $(XTRANS_DEFINES) $(NX_DEFINES) - INCLUDES = -I. -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) \ - -I$(SERVERSRC)/Xext -I$(SERVERSRC)/render \ - -I$(TOP)/lib/Xau $(NX_INCLUDES) \ - `pkg-config --cflags-only-I pixman-1` - DEPEND_DEFINES = $(XDMCP_DEFINES) $(EXT_DEFINES) \ - $(TRANS_INCLUDES) $(CONNECTION_FLAGS) $(GETPEER_DEFINES) \ - DependDefines + DEFINES = $(CONNECTION_FLAGS) \ + $(MEM_DEFINES) \ + $(XDMAUTHDEFS) \ + $(RPCDEFS) \ + $(SIGNAL_DEFINES) \ + $(OS_DEFINES) \ + $(GETPEER_DEFINES) \ + $(RANDOM_DEFINES) \ + $(BUGMSG) \ + $(XTRANS_FAILDEFINES) \ + $(XTRANS_DEFINES) \ + $(NX_DEFINES) \ + $(NULL) + + INCLUDES = -I. \ + -I../include \ + -I$(XINCLUDESRC) \ + -I$(EXTINCSRC) \ + -I$(SERVERSRC)/Xext \ + -I$(SERVERSRC)/render \ + -I$(TOP)/lib/Xau \ + $(NX_INCLUDES) \ + `pkg-config --cflags-only-I pixman-1` \ + $(NULL) + + DEPEND_DEFINES = $(XDMCP_DEFINES) \ + $(EXT_DEFINES) \ + $(TRANS_INCLUDES) \ + $(CONNECTION_FLAGS) \ + $(GETPEER_DEFINES) \ + DependDefines \ + $(NULL) + LINTLIBS = ../dix/llib-ldix.ln #ifdef NEED_ALLOCA_FROM_LIBPW -- cgit v1.2.3 From 104307dd6750205e707635940f5f3efba370f8ec Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 15 Feb 2017 13:51:26 +0000 Subject: Xserver/os/: Drop not-used-anymore MNX_TCPCONN macro. --- nx-X11/programs/Xserver/os/access.c | 17 ++++++++--------- nx-X11/programs/Xserver/os/connection.c | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c index 8236a08df..34e193bbd 100644 --- a/nx-X11/programs/Xserver/os/access.c +++ b/nx-X11/programs/Xserver/os/access.c @@ -496,7 +496,7 @@ DefineSelf (int fd) void DefineSelf (int fd) { -#if !defined(TCPCONN) && !defined(UNIXCONN) && !defined(MNX_TCPCONN) +#if !defined(TCPCONN) && !defined(UNIXCONN) return; #else register int n; @@ -631,7 +631,7 @@ DefineLocalHost: selfhosts = host; } } -#endif /* !TCPCONN && !UNIXCONN && !MNX_TCPCONN */ +#endif /* !TCPCONN && !UNIXCONN */ } #else @@ -1070,11 +1070,10 @@ ResetHosts (char *display) FILE *fd; char *ptr; int i, hostlen; -#if ((defined(TCPCONN) || defined(MNX_TCPCONN)) && \ - (!defined(IPv6) || !defined(AF_INET6))) +#if (defined(TCPCONN) && (!defined(IPv6) || !defined(AF_INET6))) union { struct sockaddr sa; -#if defined(TCPCONN) || defined(MNX_TCPCONN) +#if defined(TCPCONN) struct sockaddr_in in; #endif /* TCPCONN */ } saddr; @@ -1119,7 +1118,7 @@ ResetHosts (char *display) NewHost(family, "", 0, FALSE); LocalHostRequested = TRUE; /* Fix for XFree86 bug #156 */ } -#if defined(TCPCONN) || defined(MNX_TCPCONN) +#if defined(TCPCONN) else if (!strncmp("inet:", lhostname, 5)) { family = FamilyInternet; @@ -1164,7 +1163,7 @@ ResetHosts (char *display) } else #endif /* SECURE_RPC */ -#if defined(TCPCONN) || defined(MNX_TCPCONN) +#if defined(TCPCONN) { #if defined(IPv6) && defined(AF_INET6) if ( (family == FamilyInternet) || (family == FamilyInternet6) || @@ -1595,7 +1594,7 @@ CheckAddr ( switch (family) { -#if defined(TCPCONN) || defined(MNX_TCPCONN) +#if defined(TCPCONN) case FamilyInternet: if (length == sizeof (struct in_addr)) len = length; @@ -1688,7 +1687,7 @@ ConvertAddr ( case AF_UNIX: #endif return FamilyLocal; -#if defined(TCPCONN) || defined(MNX_TCPCONN) +#if defined(TCPCONN) case AF_INET: #ifdef WIN32 if (16777343 == *(long*)&((struct sockaddr_in *) saddr)->sin_addr) diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 74bb13404..36e405ab5 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -549,7 +549,7 @@ AuthAudit (ClientPtr client, Bool letin, #endif strcpy(out, "local host"); break; -#if defined(TCPCONN) || defined(MNX_TCPCONN) +#if defined(TCPCONN) case AF_INET: sprintf(out, "IP %s", inet_ntoa(((struct sockaddr_in *) saddr)->sin_addr)); -- cgit v1.2.3 From 0338cbc3f355cdb16da789f446dee2eb7773edba Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 15 Feb 2017 14:11:46 +0000 Subject: LBX clean-up: Drop forgotten passage in Xserver/os/connection.c. --- nx-X11/programs/Xserver/os/connection.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 36e405ab5..0a52214b0 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -534,10 +534,6 @@ AuthAudit (ClientPtr client, Bool letin, char addr[128]; char *out = addr; - if (!((OsCommPtr)client->osPrivate)->trans_conn) { - strcpy(addr, "LBX proxy at "); - out += strlen(addr); - } if (!len) strcpy(out, "local host"); else -- cgit v1.2.3 From 6bc37b980515995b0944632e5a062246683f1d97 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 15 Feb 2017 14:18:35 +0000 Subject: AUDIT messages should contain uid for local accesses (X.org bug #1997) commit fbfb35189ef6666707097704b43e052cb2f919ae Author: Alan Coopersmith Date: Wed Nov 1 15:11:48 2006 -0800 Bug #1997: AUDIT messages should contain uid for local accesses --- nx-X11/programs/Xserver/os/connection.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 0a52214b0..151605cfb 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -534,6 +534,9 @@ AuthAudit (ClientPtr client, Bool letin, char addr[128]; char *out = addr; + int client_uid; + char client_uid_string[32]; + if (!len) strcpy(out, "local host"); else @@ -563,14 +566,22 @@ AuthAudit (ClientPtr client, Bool letin, default: strcpy(out, "unknown address"); } - + + if (LocalClientCred(client, &client_uid, NULL) != -1) { + snprintf(client_uid_string, sizeof(client_uid_string), + " (uid %d)", client_uid); + } else { + client_uid_string[0] = '\0'; + } + if (proto_n) - AuditF("client %d %s from %s\n Auth name: %.*s ID: %d\n", + AuditF("client %d %s from %s%s\n Auth name: %.*s ID: %d\n", client->index, letin ? "connected" : "rejected", addr, - (int)proto_n, auth_proto, auth_id); + client_uid_string, (int)proto_n, auth_proto, auth_id); else - AuditF("client %d %s from %s\n", - client->index, letin ? "connected" : "rejected", addr); + AuditF("client %d %s from %s%s\n", + client->index, letin ? "connected" : "rejected", addr, + client_uid_string); } XID -- cgit v1.2.3 From 8996f80a5e3b205cb580aba34aa21d165ef78cfb Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 15 Feb 2017 14:42:48 +0000 Subject: Rework local client id finding code to be more uniform Backport of X.org commit: commit 2d93e69690d2c5d4a89a795ede6423796528e5df Author: Alan Coopersmith Date: Thu Sep 27 16:47:06 2007 -0700 Rework local client id finding code to be more uniform Backported-to-NX-by: Mike Gabriel Note: This commit also switches client_uid_string's size from 32 to 64 chars, as found in this X.org commit (spotted by Mihai Moldovan during code review): commit a7b944f0d96c3e0e15e75378a04def1ac96089fb Author: Alan Coopersmith Date: Wed Nov 1 16:17:49 2006 -0800 If getpeerucred() is available, include pid & zoneid in audit messages too --- nx-X11/programs/Xserver/include/os.h | 18 ++++ nx-X11/programs/Xserver/os/Imakefile | 4 +- nx-X11/programs/Xserver/os/access.c | 161 ++++++++++++++++++++------------ nx-X11/programs/Xserver/os/connection.c | 46 +++++++-- 4 files changed, 160 insertions(+), 69 deletions(-) diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index 99003922f..af84f54c0 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -321,6 +321,24 @@ extern int LocalClient(ClientPtr /* client */); extern int LocalClientCred(ClientPtr, int *, int *); +#define LCC_UID_SET (1 << 0) +#define LCC_GID_SET (1 << 1) +#define LCC_PID_SET (1 << 2) +#define LCC_ZID_SET (1 << 3) + +typedef struct { + int fieldsSet; /* Bit mask of fields set */ + int euid; /* Effective uid */ + int egid; /* Primary effective group id */ + int nSuppGids; /* Number of supplementary group ids */ + int *pSuppGids; /* Array of supplementary group ids */ + int pid; /* Process id */ + int zoneid; /* Only set on Solaris 10 & later */ +} LocalClientCredRec; + +extern int GetLocalClientCreds(ClientPtr, LocalClientCredRec **); +extern void FreeLocalClientCreds(LocalClientCredRec *); + extern int ChangeAccessControl(ClientPtr /*client*/, int /*fEnabled*/); extern int GetAccessControl(void); diff --git a/nx-X11/programs/Xserver/os/Imakefile b/nx-X11/programs/Xserver/os/Imakefile index c2e1e8699..144cb5a55 100644 --- a/nx-X11/programs/Xserver/os/Imakefile +++ b/nx-X11/programs/Xserver/os/Imakefile @@ -31,6 +31,8 @@ NULL = * If you have any extra files to be put into the library, define them here. */ +ZONEID_DEFINES = -UHAVE_GETZONEID + #if NXLibraries NX_INCLUDES = -I../../../../nxcomp @@ -235,7 +237,7 @@ alloca.o: $(PWLIB) ar x $(PWLIB) alloca.o #endif /* NEED_ALLOCA_FROM_LIBPW */ -SpecialCObjectRule(access,$(ICONFIGFILES),$(XDMCP_DEFINES) $(SOCK_DEFINES) $(IFADDRS_DEFINES)) +SpecialCObjectRule(access,$(ICONFIGFILES),$(XDMCP_DEFINES) $(SOCK_DEFINES) $(IFADDRS_DEFINES) $(ZONEID_DEFINES)) SpecialCObjectRule(auth,$(ICONFIGFILES),$(XDMCP_DEFINES)) SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES)) SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES)) diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c index 34e193bbd..152287889 100644 --- a/nx-X11/programs/Xserver/os/access.c +++ b/nx-X11/programs/Xserver/os/access.c @@ -204,10 +204,6 @@ static Bool NewHost(int /*family*/, int /*len*/, int /* addingLocalHosts */); -int LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, - int **pSuppGids, int *nSuppGids); - - /* XFree86 bug #156: To keep track of which hosts were explicitly requested in /etc/X.hosts, we've added a requested field to the HOST struct, and a LocalHostRequested variable. These default to FALSE, but are set @@ -1264,38 +1260,51 @@ Bool LocalClient(ClientPtr client) /* * Return the uid and gid of a connected local client - * or the uid/gid for nobody those ids cannot be determined * * Used by XShm to test access rights to shared memory segments */ int LocalClientCred(ClientPtr client, int *pUid, int *pGid) { - return LocalClientCredAndGroups(client, pUid, pGid, NULL, NULL); + LocalClientCredRec *lcc; + int ret = GetLocalClientCreds(client, &lcc); + + if (ret == 0) { +#ifdef HAVE_GETZONEID /* only local if in the same zone */ + if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) { + FreeLocalClientCreds(lcc); + return -1; + } +#endif + if ((lcc->fieldsSet & LCC_UID_SET) && (pUid != NULL)) + *pUid = lcc->euid; + if ((lcc->fieldsSet & LCC_GID_SET) && (pGid != NULL)) + *pGid = lcc->egid; + FreeLocalClientCreds(lcc); + } + return ret; } /* * Return the uid and all gids of a connected local client - * or the uid/gid for nobody those ids cannot be determined + * Allocates a LocalClientCredRec - caller must call FreeLocalClientCreds * - * If the caller passes non-NULL values for pSuppGids & nSuppGids, - * they are responsible for calling XFree(*pSuppGids) to release the - * memory allocated for the supplemental group ids list. - * * Used by localuser & localgroup ServerInterpreted access control forms below + * Used by AuthAudit to log where local connections came from */ int -LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, - int **pSuppGids, int *nSuppGids) +GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp) { #if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED) int fd; XtransConnInfo ci; + LocalClientCredRec *lcc; #ifdef HAS_GETPEEREID uid_t uid; gid_t gid; #elif defined(HAS_GETPEERUCRED) ucred_t *peercred = NULL; + const gid_t *gids; #elif defined(SO_PEERCRED) struct ucred peercred; socklen_t so_len = sizeof(peercred); @@ -1314,57 +1323,64 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, } #endif - if (pSuppGids != NULL) - *pSuppGids = NULL; - if (nSuppGids != NULL) - *nSuppGids = 0; + *lccp = calloc(1, sizeof(LocalClientCredRec)); + if (*lccp == NULL) + return -1; + lcc = *lccp; fd = _XSERVTransGetConnectionNumber(ci); #ifdef HAS_GETPEEREID - if (getpeereid(fd, &uid, &gid) == -1) - return -1; - if (pUid != NULL) - *pUid = uid; - if (pGid != NULL) - *pGid = gid; + if (getpeereid(fd, &uid, &gid) == -1) { + FreeLocalClientCreds(lcc); + return -1; + } + lcc->euid = uid; + lcc->egid = gid; + lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET; return 0; #elif defined(HAS_GETPEERUCRED) - if (getpeerucred(fd, &peercred) < 0) - return -1; -#ifdef sun /* Ensure process is in the same zone */ - if (getzoneid() != ucred_getzoneid(peercred)) { - ucred_free(peercred); + if (getpeerucred(fd, &peercred) < 0) { + FreeLocalClientCreds(lcc); return -1; - } -#endif - if (pUid != NULL) - *pUid = ucred_geteuid(peercred); - if (pGid != NULL) - *pGid = ucred_getegid(peercred); - if (pSuppGids != NULL && nSuppGids != NULL) { - const gid_t *gids; - *nSuppGids = ucred_getgroups(peercred, &gids); - if (*nSuppGids > 0) { - *pSuppGids = malloc(sizeof(int) * (*nSuppGids)); - if (*pSuppGids == NULL) { - *nSuppGids = 0; - } else { - int i; - for (i = 0 ; i < *nSuppGids; i++) { - (*pSuppGids)[i] = (int) gids[i]; - } + lcc->euid = ucred_geteuid(peercred); + if (lcc->euid != -1) + lcc->fieldsSet |= LCC_UID_SET; + lcc->egid = ucred_getegid(peercred); + if (lcc->egid != -1) + lcc->fieldsSet |= LCC_GID_SET; + lcc->pid = ucred_getpid(peercred); + if (lcc->pid != -1) + lcc->fieldsSet |= LCC_PID_SET; +#ifdef HAVE_GETZONEID + lcc->zoneid = ucred_getzoneid(peercred); + if (lcc->zoneid != -1) + lcc->fieldsSet |= LCC_ZID_SET; +#endif + lcc->nSuppGids = ucred_getgroups(peercred, &gids); + if (lcc->nSuppGids > 0) { + lcc->pSuppGids = calloc((lcc->nSuppGids), sizeof(int)); + if (lcc->pSuppGids == NULL) { + lcc->nSuppGids = 0; + } else { + int i; + for (i = 0 ; i < lcc->nSuppGids; i++) { + (lcc->pSuppGids)[i] = (int) gids[i]; } } + } else { + lcc->nSuppGids = 0; } ucred_free(peercred); return 0; #elif defined(SO_PEERCRED) - if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) - return -1; - if (pUid != NULL) - *pUid = peercred.uid; - if (pGid != NULL) - *pGid = peercred.gid; + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) { + FreeLocalClientCreds(lcc); + return -1; + } + lcc->euid = peercred.uid; + lcc->egid = peercred.gid; + lcc->pid = peercred.pid; + lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET; return 0; #endif #else @@ -1374,6 +1390,17 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, #endif } +void +FreeLocalClientCreds(LocalClientCredRec *lcc) +{ + if (lcc != NULL) { + if (lcc->nSuppGids > 0) { + free(lcc->pSuppGids); + } + free(lcc); + } +} + static Bool AuthorizedClient(ClientPtr client) { @@ -2177,38 +2204,48 @@ static Bool siLocalCredAddrMatch(int family, void * addr, int len, const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv) { - int connUid, connGid, *connSuppGids, connNumSuppGids, siAddrId; + int siAddrId; + LocalClientCredRec *lcc; siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv; - if (LocalClientCredAndGroups(client, &connUid, &connGid, - &connSuppGids, &connNumSuppGids) == -1) { + if (GetLocalClientCreds(client, &lcc) == -1) { return FALSE; } +#ifdef HAVE_GETZONEID /* Ensure process is in the same zone */ + if ((lcc->fieldsSet & LCC_ZID_SET) && (lcc->zoneid != getzoneid())) { + FreeLocalClientCreds(lcc); + return FALSE; + } +#endif + if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) { + FreeLocalClientCreds(lcc); return FALSE; } if (lcPriv->credType == LOCAL_USER) { - if (connUid == siAddrId) { + if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) { + FreeLocalClientCreds(lcc); return TRUE; } } else { - if (connGid == siAddrId) { + if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) { + FreeLocalClientCreds(lcc); return TRUE; } - if (connSuppGids != NULL) { + if (lcc->pSuppGids != NULL) { int i; - for (i = 0 ; i < connNumSuppGids; i++) { - if (connSuppGids[i] == siAddrId) { - free(connSuppGids); + for (i = 0 ; i < lcc->nSuppGids; i++) { + if (lcc->pSuppGids[i] == siAddrId) { + FreeLocalClientCreds(lcc); return TRUE; } } - free(connSuppGids); } } + FreeLocalClientCreds(lcc); return FALSE; } diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 151605cfb..538996198 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -534,8 +534,8 @@ AuthAudit (ClientPtr client, Bool letin, char addr[128]; char *out = addr; - int client_uid; - char client_uid_string[32]; + char client_uid_string[64]; + LocalClientCredRec *lcc; if (!len) strcpy(out, "local host"); @@ -567,10 +567,44 @@ AuthAudit (ClientPtr client, Bool letin, strcpy(out, "unknown address"); } - if (LocalClientCred(client, &client_uid, NULL) != -1) { - snprintf(client_uid_string, sizeof(client_uid_string), - " (uid %d)", client_uid); - } else { + if (GetLocalClientCreds(client, &lcc) != -1) { + int slen; /* length written to client_uid_string */ + + strcpy(client_uid_string, " ( "); + slen = 3; + + if (lcc->fieldsSet & LCC_UID_SET) { + snprintf(client_uid_string + slen, + sizeof(client_uid_string) - slen, + "uid=%ld ", (long) lcc->euid); + slen = strlen(client_uid_string); + } + + if (lcc->fieldsSet & LCC_GID_SET) { + snprintf(client_uid_string + slen, + sizeof(client_uid_string) - slen, + "gid=%ld ", (long) lcc->egid); + slen = strlen(client_uid_string); + } + + if (lcc->fieldsSet & LCC_PID_SET) { + snprintf(client_uid_string + slen, + sizeof(client_uid_string) - slen, + "pid=%ld ", (long) lcc->pid); + slen = strlen(client_uid_string); + } + + if (lcc->fieldsSet & LCC_ZID_SET) { + snprintf(client_uid_string + slen, + sizeof(client_uid_string) - slen, + "zoneid=%ld ", (long) lcc->zoneid); + slen = strlen(client_uid_string); + } + + snprintf(client_uid_string + slen, sizeof(client_uid_string) - slen, ")"); + FreeLocalClientCreds(lcc); + } + else { client_uid_string[0] = '\0'; } -- cgit v1.2.3 From 6c076cfe5a656b03d4bd0dd9742e7a02dce2b957 Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Thu, 16 Feb 2017 10:28:32 +0100 Subject: os: Fix a memory leak Backported from X.org (+ coding style fixes in other free() calls): commit 617b7d22115ccaaaa7ec69c99885054d33a3bc37 Author: Pauli Nieminen Date: Thu Dec 30 19:19:42 2010 +0200 os: Fix a memory leak Signed-off-by: Pauli Nieminen Reviewed-by: Alan Coopersmith Reviewed-by: Daniel Stone Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/access.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c index 152287889..d745bde3a 100644 --- a/nx-X11/programs/Xserver/os/access.c +++ b/nx-X11/programs/Xserver/os/access.c @@ -1240,20 +1240,22 @@ Bool LocalClient(ClientPtr client) &alen, (void **)&addr); if (family == -1) { - free ((char *) from); + free(from); return FALSE; } if (family == FamilyLocal) { - free ((char *) from); + free(from); return TRUE; } for (host = selfhosts; host; host = host->next) { - if (addrEqual (family, addr, alen, host)) + if (addrEqual (family, addr, alen, host)) { + free(from); return TRUE; + } } - free ((char *) from); + free(from); } return FALSE; } -- cgit v1.2.3 From f14f738a627b5a6f6c1242f4fe123e4cc9e9c811 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 16 Feb 2017 15:04:43 +0000 Subject: dix/os: Merge priority computation into SmartScheduleClient Backported from X.org: commit 7762a602c1dfdd8cfcf2b8c2281cf4d683d05216 Author: Keith Packard Date: Thu May 19 15:05:55 2016 -0700 dix/os: Merge priority computation into SmartScheduleClient Instead of having scheduling done in two places (one in WaitForSomething, and the other in SmartScheduleClient), just stick all of the scheduling in SmartScheduleClient. Signed-off-by: Keith Packard Reviewed-by: Adam Jackson Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/dispatch.c | 25 ++++++++++++--------- nx-X11/programs/Xserver/os/WaitFor.c | 41 ++++------------------------------ 2 files changed, 18 insertions(+), 48 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index 7b2aa7b3d..68c207e33 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -240,15 +240,13 @@ void InitProcVectors(void); int SmartScheduleClient (int *clientReady, int nready) { - ClientPtr pClient; int i; int client; - int bestPrio, best = 0; + ClientPtr pClient, best = NULL; int bestRobin, robin; long now = SmartScheduleTime; long idle; - bestPrio = -0x7fffffff; bestRobin = 0; idle = 2 * SmartScheduleSlice; for (i = 0; i < nready; i++) @@ -264,13 +262,19 @@ SmartScheduleClient (int *clientReady, int nready) pClient->smart_check_tick = now; /* check priority to select best client */ - robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff; - if (pClient->smart_priority > bestPrio || - (pClient->smart_priority == bestPrio && robin > bestRobin)) + robin = (pClient->index - + SmartLastIndex[pClient->smart_priority - + SMART_MIN_PRIORITY]) & 0xff; + + /* pick the best client */ + if (!best || + pClient->priority > best->priority || + (pClient->priority == best->priority && + (pClient->smart_priority > best->smart_priority || + (pClient->smart_priority == best->smart_priority && robin > bestRobin)))) { - bestPrio = pClient->smart_priority; + best = pClient; bestRobin = robin; - best = client; } #ifdef SMART_DEBUG if ((now - SmartLastPrint) >= 5000) @@ -284,8 +288,7 @@ SmartScheduleClient (int *clientReady, int nready) SmartLastPrint = now; } #endif - pClient = clients[best]; - SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index; + SmartLastIndex[best->smart_priority - SMART_MIN_PRIORITY] = best->index; /* * Set current client pointer */ @@ -314,7 +317,7 @@ SmartScheduleClient (int *clientReady, int nready) { SmartScheduleSlice = SmartScheduleInterval; } - return best; + return best->index; } #ifndef NXAGENT_SERVER diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c index 3ac2e1c7e..02c460f0c 100644 --- a/nx-X11/programs/Xserver/os/WaitFor.c +++ b/nx-X11/programs/Xserver/os/WaitFor.c @@ -544,17 +544,14 @@ WaitForSomething(int *pClientsReady) #ifndef WIN32 for (i=0; ipriority; - if (nready == 0 || client_priority > highest_priority) - { - /* Either we found the first client, or we found - * a client whose priority is greater than all others - * that have been found so far. Either way, we want - * to initialize the list of clients to contain just - * this client. - */ - pClientsReady[0] = client_index; - highest_priority = client_priority; - nready = 1; - } - /* the following if makes sure that multiple same-priority - * clients get batched together - */ - else if (client_priority == highest_priority) -#endif - { - pClientsReady[nready++] = client_index; - } + pClientsReady[nready++] = client_index; #ifndef WIN32 - clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient); - } + clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient); + } #else FD_CLR(curclient, &clientsReadable); #endif -- cgit v1.2.3 From 366067b7c3678148bff858239e3c16e0d6043e03 Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Thu, 16 Feb 2017 15:21:34 +0000 Subject: dix/os: backport various signal handling and smart scheduler changes from X.org Backported from X.org: commit 6178b1c91cfc9e860914acc6f0be2f2d2e07a124 Author: Adam Jackson Date: Tue Jun 7 15:52:11 2016 -0400 dix: Use OsSignal() not signal() As the man page for the latter states: The effects of signal() in a multithreaded process are unspecified. We already have an interface to call sigaction() instead, use it. Signed-off-by: Adam Jackson Reviewed-by: Keith Packard commit e10ba9e4b52269b2ac75c4802dce4ca47d169657 Author: Keith Packard Date: Wed Nov 11 22:02:01 2015 -0800 Remove non-smart scheduler. Don't require setitimer. This allows the server to call GetTimeInMillis() after each request is processed to avoid needing setitimer. -dumbSched now turns off the setitimer. Reviewed-by: Adam Jackson Signed-off-by: Keith Packard commit 1f915e8b524dd02011158aa038935970684c7630 Author: Daniel Drake Date: Wed May 20 13:16:12 2015 -0600 Keep SIGALRM restart flag after Popen Commit 94ab7455 added SA_RESTART to the SIGALRM handler. However, the Popen code tears down and recreates the SIGALRM handler via OsSignal(), and this flag is dropped at this time. Clean the code to use just a single codepath for creating this signal handler, always applying SA_RESTART. [ajax: Fixed commit id] Reviewed-by: Adam Jackson Signed-off-by: Daniel Drake commit 94ab7455abc213fc96760e29ab2e943ec682fb22 Author: Daniel Drake Date: Tue May 12 16:39:22 2015 -0600 Allow system call restarts upon signal interruption The X server frequently deals with SIGIO and SIGALRM interruptions. If process execution is inside certain blocking system calls when these signals arrive, e.g. with the kernel blocked on a contended semaphore, the system calls will be interrupted. Some system calls are automatically restartable (the kernel re-executes them with the same parameters once the signal handler returns) but only if the signal handler allows it. Set SA_RESTART on the signal handlers to enable this convenient behaviour. Reviewed-by: Adam Jackson Signed-off-by: Daniel Drake commit a6c71ce5d2d2fe89e07a2ef5041c915acc3dc686 Author: Tiago Vignatti Date: Mon Mar 28 19:21:28 2011 +0300 os: fix memory and fd leaks in Popen Signed-off-by: Tiago Vignatti Reviewed-by: Peter Hutterer Reviewed-by: Nicolas Peninguy commit c9051b684b524549eab6d5b88ee3e195a6f6fbe8 Author: Alan Coopersmith Date: Wed Nov 5 18:25:57 2008 -0800 Use OsSignal in Popen/Pclose to avoid SysV signal() stupidity commit 0e9ef65fa583bf2393dd0fda82df6f092387b425 Author: Keith Packard Date: Wed Nov 7 16:33:10 2007 -0800 Don't frob timers unless SmartSchedule is running commit 2338d5c9914e2a43c3a4f7ee0f4355ad0a1ad9e7 Author: Arjan van de Ven Date: Sun Oct 28 09:37:52 2007 +0100 reduce wakeups from smart scheduler The smart scheduler itimer currently always fires after each request (which in turn causes the CPU to wake out of idle, burning precious power). Rather than doing this, just stop the timer before going into the select() portion of the WaitFor loop. It's a cheap system call, and it will only get called if there's no more commands batched up from the active fd. This change also allows some of the functions to be simplified; setitimer() will only fail if it's passed invalid data, and we don't do that... so make it void and remove all the conditional code that deals with failure. The change also allows us to remove a few variables that were used for housekeeping between the signal handler and the main loop. Signed-off-by: Keith Packard **Note**: The above change also required ABI changes in hw/nxagent/. commit abe0a51f3f790f8c055289465e130177c4b647cc Author: Ben Byer Date: Fri Sep 21 17:07:36 2007 -0700 So, like, checking return codes of system calls (signal, etc) is good. Also, only restore an old signal handler if one was actually set (prevents the server from dying on OS X). commit 6da39c67905500ab2db00a45cda4a9f756cdde96 Author: Eric Anholt Date: Wed Sep 12 13:23:13 2007 +0000 Fix build on FreeBSD after Popen changes. commit a5b8053606d6e786cdcf6734f271acc05f9cc588 Author: Adam Jackson Date: Tue Sep 11 11:37:06 2007 -0400 Ignore - not just block - SIGALRM around Popen()/Pclose(). Because our "popen" implementation uses stdio, and because nobody's stdio library is capable of surviving signals, we need to make absolutely sure that we hide the SIGALRM from the smart scheduler. Otherwise, when you open a menu in openoffice, and it recompiles XKB to deal with the accelerators, and you popen xkbcomp because we suck, then the scheduler will tell you you're taking forever doing something stupid, and the wait() code will get confused, and input will hang and your CPU usage slams to 100%. Down, not across. Backported-to-NX-by: Mike Gabriel --- nx-X11/config/cf/Imake.tmpl | 9 +- nx-X11/programs/Xserver/Xext/shm.c | 5 +- nx-X11/programs/Xserver/Xext/xf86bigfont.c | 6 +- nx-X11/programs/Xserver/dix/dispatch.c | 16 ++- nx-X11/programs/Xserver/hw/nxagent/Display.c | 2 +- nx-X11/programs/Xserver/hw/nxagent/Display.h | 29 ++--- nx-X11/programs/Xserver/hw/nxagent/Handlers.c | 8 +- nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c | 9 +- nx-X11/programs/Xserver/include/dixstruct.h | 17 +-- nx-X11/programs/Xserver/os/WaitFor.c | 28 ++-- nx-X11/programs/Xserver/os/io.c | 13 +- nx-X11/programs/Xserver/os/osinit.c | 5 +- nx-X11/programs/Xserver/os/utils.c | 164 ++++++++++++++---------- 13 files changed, 159 insertions(+), 152 deletions(-) diff --git a/nx-X11/config/cf/Imake.tmpl b/nx-X11/config/cf/Imake.tmpl index d4b033888..944af2fdc 100644 --- a/nx-X11/config/cf/Imake.tmpl +++ b/nx-X11/config/cf/Imake.tmpl @@ -1289,6 +1289,12 @@ TCLIBDIR = TclLibDir #ifndef ToolkitStringsABIOptions #define ToolkitStringsABIOptions /**/ #endif +#ifndef HasSetitimer +#define HasSetitimer YES +#endif +#ifndef HasSetitimerDefines +#define HasSetitimerDefines -DHAVE_SETITIMER=1 +#endif #ifndef HasLdRunPath #define HasLdRunPath NO #endif @@ -1841,6 +1847,7 @@ MODLDCOMBINEFLAGS = ModuleLdCombineFlags STD_CPP_OPTIONS = StandardCppOptions STD_CPP_DEFINES = StandardCppOptions StandardCppDefines $(PROJECT_DEFINES) STD_DEFINES = StandardDefines $(PROJECT_DEFINES) +SETITIMER_DEFINES = HasSetitimerDefines EXTRA_LOAD_FLAGS = ExtraLoadFlags EXTRA_LDOPTIONS = ExtraLoadOptions EXTRA_LIBRARIES = MallocLibraries ExtraLibraries @@ -1966,7 +1973,7 @@ MODLDCOMBINEFLAGS = ModuleLdCombineFlags * LOCAL_LDFLAGS contains client-specific ld flags flags set in Imakefile */ ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(INSTALLED_INCLUDES) $(STD_INCLUDES) - ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(THREADS_DEFINES) $(MODULE_DEFINES) $(DEFINES) $(EXTRA_DEFINES) + ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(SETITIMER_DEFINES) $(PROTO_DEFINES) $(THREADS_DEFINES) $(MODULE_DEFINES) $(DEFINES) $(EXTRA_DEFINES) CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(THREADS_CFLAGS) $(MODULE_CFLAGS) $(ALLDEFINES) LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) $(DEPEND_DEFINES) LDPRELIB = LdPreLib $(INSTALLED_LIBS) diff --git a/nx-X11/programs/Xserver/Xext/shm.c b/nx-X11/programs/Xserver/Xext/shm.c index 263adc3df..274284151 100644 --- a/nx-X11/programs/Xserver/Xext/shm.c +++ b/nx-X11/programs/Xserver/Xext/shm.c @@ -150,7 +150,6 @@ static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage}; #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) -#include static Bool badSysCall = FALSE; @@ -167,7 +166,7 @@ static Bool CheckForShmSyscall() int shmid = -1; /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ - oldHandler = signal(SIGSYS, SigSysHandler); + oldHandler = OsSignal(SIGSYS, SigSysHandler); badSysCall = FALSE; shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); @@ -182,7 +181,7 @@ static Bool CheckForShmSyscall() /* Allocation failed */ badSysCall = TRUE; } - signal(SIGSYS, oldHandler); + OsSignal(SIGSYS, oldHandler); return(!badSysCall); } diff --git a/nx-X11/programs/Xserver/Xext/xf86bigfont.c b/nx-X11/programs/Xserver/Xext/xf86bigfont.c index 0ad411fc3..107b0f23f 100644 --- a/nx-X11/programs/Xserver/Xext/xf86bigfont.c +++ b/nx-X11/programs/Xserver/Xext/xf86bigfont.c @@ -106,8 +106,6 @@ static Bool badSysCall = FALSE; #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) -#include - static void SigSysHandler( int signo) @@ -122,7 +120,7 @@ CheckForShmSyscall(void) int shmid = -1; /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ - oldHandler = signal(SIGSYS, SigSysHandler); + oldHandler = OsSignal(SIGSYS, SigSysHandler); badSysCall = FALSE; shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); @@ -136,7 +134,7 @@ CheckForShmSyscall(void) /* Allocation failed */ badSysCall = TRUE; } - signal(SIGSYS, oldHandler); + OsSignal(SIGSYS, oldHandler); return (!badSysCall); } diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index 68c207e33..3869ef723 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -221,7 +221,11 @@ InitSelections() #define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ #define SMART_SCHEDULE_MAX_SLICE 200 /* ms */ -Bool SmartScheduleDisable = FALSE; +#ifdef HAVE_SETITIMER +#define SMART_SCHEDULE_DEFAULT_SIGNAL_ENABLE HAVE_SETITIMER +Bool SmartScheduleSignalEnable = SMART_SCHEDULE_DEFAULT_SIGNAL_ENABLE; +#endif + long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; @@ -351,7 +355,7 @@ Dispatch(void) nready = WaitForSomething(clientReady); - if (nready && !SmartScheduleDisable) + if (nready) { clientReady[0] = SmartScheduleClient (clientReady, nready); nready = 1; @@ -386,8 +390,7 @@ Dispatch(void) ProcessInputEvents(); FlushIfCriticalOutputPending(); } - if (!SmartScheduleDisable && - (SmartScheduleTime - start_tick) >= SmartScheduleSlice) + if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice) { /* Penalize clients which consume ticks */ if (client->smart_priority > SMART_MIN_PRIORITY) @@ -415,7 +418,10 @@ Dispatch(void) result = BadLength; else result = (* client->requestVector[MAJOROP])(client); - + + if (!SmartScheduleSignalEnable) + SmartScheduleTime = GetTimeInMillis(); + if (result != Success) { if (client->noClientException != Success) diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.c b/nx-X11/programs/Xserver/hw/nxagent/Display.c index c683751f6..c764f50ae 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Display.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Display.c @@ -669,7 +669,7 @@ static void nxagentDisplayBlockHandler(Display *display, int reason) nxagentBlocking = 1; - if (SmartScheduleDisable == 1) + if (!SmartScheduleSignalEnable) { /* diff --git a/nx-X11/programs/Xserver/hw/nxagent/Display.h b/nx-X11/programs/Xserver/hw/nxagent/Display.h index 75da371d8..759b0de35 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Display.h +++ b/nx-X11/programs/Xserver/hw/nxagent/Display.h @@ -116,36 +116,29 @@ Bool nxagentReconnectDisplay(void *p0); * Deal with the smart scheduler. */ +#if HAVE_SETITIMER #define nxagentInitTimer() \ \ SmartScheduleInit(); #define nxagentStopTimer() \ \ - if (SmartScheduleTimerStopped == 0) \ - { \ - SmartScheduleStopTimer(); \ - } \ -\ - SmartScheduleIdle = 1; + SmartScheduleStopTimer(); \ #define nxagentStartTimer() \ \ - if (SmartScheduleTimerStopped == 1) \ - { \ - SmartScheduleStartTimer(); \ - } \ -\ - SmartScheduleIdle = 0; + SmartScheduleStartTimer(); #define nxagentDisableTimer() \ \ - if (SmartScheduleTimerStopped == 0) \ - { \ - SmartScheduleStopTimer(); \ - } \ -\ - SmartScheduleDisable = 1; + SmartScheduleStopTimer(); \ + SmartScheduleSignalEnable = FALSE; +#else +#define nxagentInitTimer() +#define nxagentStopTimer() +#define nxagentStartTimer() +#define nxagentDisableTimer() +#endif /* HAVE_SETITIMER */ /* * File descriptor currently used by diff --git a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c index 8e80a1524..634f7aafd 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/Handlers.c +++ b/nx-X11/programs/Xserver/hw/nxagent/Handlers.c @@ -597,7 +597,7 @@ void nxagentWakeupHandler(void * data, int count, void * mask) nxagentHandleConnectionStates(); } - if (SmartScheduleDisable == 1) + if (!SmartScheduleSignalEnable) { #ifdef DEBUG @@ -885,7 +885,7 @@ void nxagentShadowWakeupHandler(void * data, int count, void * mask) nxagentHandleConnectionStates(); } - if (SmartScheduleDisable == 1) + if (!SmartScheduleSignalEnable) { #ifdef DEBUG @@ -1075,7 +1075,7 @@ void nxagentDispatchHandler(ClientPtr client, int in, int out) #endif } - if (SmartScheduleDisable == 1) + if (!SmartScheduleSignalEnable) { /* @@ -1150,7 +1150,7 @@ void nxagentDispatchHandler(ClientPtr client, int in, int out) * the inner dispatch loop forever. */ - if (SmartScheduleDisable == 1) + if (!SmartScheduleSignalEnable) { if (client -> index != nxagentDispatch.client) diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c index 652d54479..5792a41c5 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c +++ b/nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c @@ -387,7 +387,7 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio #endif - if (nready && !SmartScheduleDisable) + if (nready) { clientReady[0] = SmartScheduleClient (clientReady, nready); nready = 1; @@ -422,8 +422,7 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio ProcessInputEvents(); FlushIfCriticalOutputPending(); } - if (!SmartScheduleDisable && - (SmartScheduleTime - start_tick) >= SmartScheduleSlice) + if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice) { /* Penalize clients which consume ticks */ if (client->smart_priority > SMART_MIN_PRIORITY) @@ -512,6 +511,10 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio result = (* client->requestVector[MAJOROP])(client); #endif + + if (!SmartScheduleSignalEnable) + SmartScheduleTime = GetTimeInMillis(); + if (result != Success) { if (client->noClientException != Success) diff --git a/nx-X11/programs/Xserver/include/dixstruct.h b/nx-X11/programs/Xserver/include/dixstruct.h index 3c97e5bb7..1096f5c40 100644 --- a/nx-X11/programs/Xserver/include/dixstruct.h +++ b/nx-X11/programs/Xserver/include/dixstruct.h @@ -150,18 +150,19 @@ extern long SmartScheduleTime; extern long SmartScheduleInterval; extern long SmartScheduleSlice; extern long SmartScheduleMaxSlice; -extern unsigned long SmartScheduleIdleCount; -extern Bool SmartScheduleDisable; -extern Bool SmartScheduleIdle; -extern Bool SmartScheduleTimerStopped; -extern Bool SmartScheduleStartTimer(void); -#ifdef NXAGENT_SERVER -extern Bool SmartScheduleStopTimer(void); +#ifdef HAVE_SETITIMER +#if HAVE_SETITIMER +extern Bool SmartScheduleSignalEnable; +#else +#define SmartScheduleSignalEnable FALSE +#endif #endif +extern void SmartScheduleStartTimer(void); +extern void SmartScheduleStopTimer(void); #define SMART_MAX_PRIORITY (20) #define SMART_MIN_PRIORITY (-20) -extern Bool SmartScheduleInit(void); +extern void SmartScheduleInit(void); /* This prototype is used pervasively in Xext, dix */ #define DISPATCH_PROC(func) int func(ClientPtr /* client */) diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c index 02c460f0c..4d7fe3f84 100644 --- a/nx-X11/programs/Xserver/os/WaitFor.c +++ b/nx-X11/programs/Xserver/os/WaitFor.c @@ -213,18 +213,10 @@ WaitForSomething(int *pClientsReady) ProcessWorkQueue(); if (XFD_ANYSET (&ClientsWithInput)) { - if (!SmartScheduleDisable) - { - someReady = TRUE; - waittime.tv_sec = 0; - waittime.tv_usec = 0; - wt = &waittime; - } - else - { - XFD_COPYSET (&ClientsWithInput, &clientsReadable); - break; - } + someReady = TRUE; + waittime.tv_sec = 0; + waittime.tv_usec = 0; + wt = &waittime; } if (someReady) { @@ -247,7 +239,8 @@ WaitForSomething(int *pClientsReady) } XFD_COPYSET(&AllSockets, &LastSelectMask); } - SmartScheduleIdle = TRUE; + SmartScheduleStopTimer (); + BlockHandler((void *)&wt, (void *)&LastSelectMask); if (NewOutputPending) FlushAllOutput(); @@ -387,13 +380,8 @@ WaitForSomething(int *pClientsReady) i = XTestProcessInputAction (i, &waittime); } #endif /* XTESTEXT1 */ - if (i >= 0) - { - SmartScheduleIdle = FALSE; - SmartScheduleIdleCount = 0; - if (SmartScheduleTimerStopped) - (void) SmartScheduleStartTimer (); - } + SmartScheduleStartTimer (); + if (i <= 0) /* An error or timeout occurred */ { #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) diff --git a/nx-X11/programs/Xserver/os/io.c b/nx-X11/programs/Xserver/os/io.c index 075eb677c..07399438e 100644 --- a/nx-X11/programs/Xserver/os/io.c +++ b/nx-X11/programs/Xserver/os/io.c @@ -465,24 +465,15 @@ ReadRequestFromClient(ClientPtr client) FD_SET(fd, &ClientsWithInput); else { - if (!SmartScheduleDisable) - FD_CLR(fd, &ClientsWithInput); - else - YieldControlNoInput(); + FD_CLR(fd, &ClientsWithInput); } } else { if (!gotnow) AvailableInput = oc; - if (!SmartScheduleDisable) - FD_CLR(fd, &ClientsWithInput); - else - YieldControlNoInput(); + FD_CLR(fd, &ClientsWithInput); } - if (SmartScheduleDisable) - if (++timesThisConnection >= MAX_TIMES_PER) - YieldControl(); #ifdef BIGREQS if (move_header) { diff --git a/nx-X11/programs/Xserver/os/osinit.c b/nx-X11/programs/Xserver/os/osinit.c index 08fbb8c89..a660337ca 100644 --- a/nx-X11/programs/Xserver/os/osinit.c +++ b/nx-X11/programs/Xserver/os/osinit.c @@ -217,9 +217,8 @@ OsInit(void) * log file name if logging to a file is desired. */ LogInit(NULL, NULL); - if (!SmartScheduleDisable) - if (!SmartScheduleInit ()) - SmartScheduleDisable = TRUE; + SmartScheduleInit(); + OsInitAllocator(); } diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index af793454f..25cbb1e87 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -290,7 +290,8 @@ OsSignal(sig, handler) sigaddset(&act.sa_mask, sig); act.sa_flags = 0; act.sa_handler = handler; - sigaction(sig, &act, &oact); + if (sigaction(sig, &act, &oact)) + perror("sigaction"); return oact.sa_handler; #endif } @@ -1026,10 +1027,12 @@ ProcessCommandLine(int argc, char *argv[]) i = skip - 1; } #endif +#if HAVE_SETITIMER else if ( strcmp( argv[i], "-dumbSched") == 0) { - SmartScheduleDisable = TRUE; + SmartScheduleSignalEnable = FALSE; } +#endif else if ( strcmp( argv[i], "-schedInterval") == 0) { if (++i < argc) @@ -1353,30 +1356,15 @@ XNFstrdup(const char *s) return ret; } -unsigned long SmartScheduleIdleCount; -Bool SmartScheduleIdle; -Bool SmartScheduleTimerStopped; - -#ifdef SIGVTALRM -#define SMART_SCHEDULE_POSSIBLE -#endif - -#ifdef SMART_SCHEDULE_POSSIBLE -#define SMART_SCHEDULE_SIGNAL SIGALRM -#define SMART_SCHEDULE_TIMER ITIMER_REAL -#endif - -#ifdef NX_TRANS_SOCKET void SmartScheduleStopTimer (void) -#else -static void -SmartScheduleStopTimer (void) -#endif { -#ifdef SMART_SCHEDULE_POSSIBLE +#if HAVE_SETITIMER struct itimerval timer; + if (!SmartScheduleSignalEnable) + return; + #ifdef NX_TRANS_TEST fprintf(stderr, "SmartScheduleStopTimer: Stopping timer.\n"); #endif @@ -1386,96 +1374,101 @@ SmartScheduleStopTimer (void) timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 0; (void) setitimer (ITIMER_REAL, &timer, 0); - SmartScheduleTimerStopped = TRUE; #endif } -Bool +void SmartScheduleStartTimer (void) { -#ifdef SMART_SCHEDULE_POSSIBLE +#if HAVE_SETITIMER struct itimerval timer; - #ifdef NX_TRANS_SOCKET - - if (SmartScheduleDisable) - { - return FALSE; - } - - #endif + if (!SmartScheduleSignalEnable) + return; #ifdef NX_TRANS_TEST fprintf(stderr, "SmartScheduleStartTimer: Starting timer with [%ld] ms.\n", SmartScheduleInterval); #endif - SmartScheduleTimerStopped = FALSE; timer.it_interval.tv_sec = 0; timer.it_interval.tv_usec = SmartScheduleInterval * 1000; timer.it_value.tv_sec = 0; timer.it_value.tv_usec = SmartScheduleInterval * 1000; - return setitimer (ITIMER_REAL, &timer, 0) >= 0; + setitimer (ITIMER_REAL, &timer, 0); #endif - return FALSE; } -#ifdef SMART_SCHEDULE_POSSIBLE +#if HAVE_SETITIMER static void SmartScheduleTimer (int sig) { - int olderrno = errno; - SmartScheduleTime += SmartScheduleInterval; #ifdef NX_TRANS_TEST fprintf(stderr, "SmartScheduleTimer: Got timer with time [%ld] ms.\n", SmartScheduleTime); #endif - - if (SmartScheduleIdle) - { - SmartScheduleStopTimer (); - } - errno = olderrno; } -#endif -Bool -SmartScheduleInit (void) +int +SmartScheduleEnable (void) { -#ifdef SMART_SCHEDULE_POSSIBLE + int ret = 0; struct sigaction act; - if (SmartScheduleDisable) - return TRUE; - + if (!SmartScheduleSignalEnable) + return 0; + #ifdef NX_TRANS_TEST - fprintf(stderr, "SmartScheduleInit: Initializing the smart scheduler.\n"); + fprintf(stderr, "SmartScheduleEnable: Enabling the smart scheduler.\n"); #endif - bzero ((char *) &act, sizeof(struct sigaction)); + memset((char *) &act, 0, sizeof(struct sigaction)); /* Set up the timer signal function */ + act.sa_flags = SA_RESTART; act.sa_handler = SmartScheduleTimer; sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SMART_SCHEDULE_SIGNAL); - if (sigaction (SMART_SCHEDULE_SIGNAL, &act, 0) < 0) - { - perror ("sigaction for smart scheduler"); - return FALSE; - } - /* Set up the virtual timer */ - if (!SmartScheduleStartTimer ()) - { - perror ("scheduling timer"); - return FALSE; + sigaddset (&act.sa_mask, SIGALRM); + ret = sigaction(SIGALRM, &act, 0); + return ret; +} + +static int +SmartSchedulePause(void) +{ + int ret = 0; + struct sigaction act; + + if (!SmartScheduleSignalEnable) + return 0; + + #ifdef NX_TRANS_TEST + fprintf(stderr, "SmartSchedulePause: Pausing the smart scheduler.\n"); + #endif + + memset((char *) &act, 0, sizeof(struct sigaction)); + + act.sa_handler = SIG_IGN; + sigemptyset(&act.sa_mask); + ret = sigaction(SIGALRM, &act, 0); + return ret; +} +#endif + +void +SmartScheduleInit(void) +{ +#if HAVE_SETITIMER + #ifdef NX_TRANS_TEST + fprintf(stderr, "SmartScheduleInit: Initializing the smart scheduler.\n"); + #endif + + if (SmartScheduleEnable() < 0) { + perror("sigaction for smart scheduler"); + SmartScheduleSignalEnable = FALSE; } - /* stop the timer and wait for WaitForSomething to start it */ - SmartScheduleStopTimer (); - return TRUE; -#else - return FALSE; #endif } @@ -1558,7 +1551,11 @@ System(char *command) return(1); #ifdef SIGCHLD - csig = signal(SIGCHLD, SIG_DFL); + csig = OsSignal(SIGCHLD, SIG_DFL); + if (csig == SIG_ERR) { + perror("signal"); + return -1; + } #endif #ifdef DEBUG @@ -1596,7 +1593,10 @@ System(char *command) #endif #ifdef SIGCHLD - signal(SIGCHLD, csig); + if (OsSignal(SIGCHLD, csig) == SIG_ERR) { + perror("signal"); + return -1; + } #endif return p == -1 ? -1 : status; @@ -1629,6 +1629,17 @@ Popen(char *command, char *type) return NULL; } + /* Ignore the smart scheduler while this is going on */ +#if HAVE_SETITIMER + if (SmartSchedulePause() < 0) { + close(pdes[0]); + close(pdes[1]); + free(cur); + perror("signal"); + return NULL; + } +#endif + #ifdef NX_TRANS_EXIT if (OsVendorStartRedirectErrorFProc != NULL) { OsVendorStartRedirectErrorFProc(); @@ -1640,6 +1651,10 @@ Popen(char *command, char *type) close(pdes[0]); close(pdes[1]); free(cur); +#if HAVE_SETITIMER + if (SmartScheduleEnable() < 0) + perror("signal"); +#endif #ifdef NX_TRANS_EXIT if (OsVendorEndRedirectErrorFProc != NULL) { OsVendorEndRedirectErrorFProc(); @@ -1714,6 +1729,13 @@ Popen(char *command, char *type) OsReleaseSignals (); #endif +#if HAVE_SETITIMER + if (SmartScheduleEnable() < 0) { + perror("signal"); + return NULL; + } +#endif + execl("/bin/sh", "sh", "-c", command, (char *)NULL); _exit(127); } -- cgit v1.2.3 From 239fe3d0802b12ce8947741693244ff8154fa559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rami=20Ylim=C3=A4ki?= Date: Wed, 15 Feb 2017 16:42:14 +0100 Subject: os: Add facilities for client ID tracking. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 6d6d4cb6043905d850834946e9bfc526ed5a9ef7 Author: Matthieu Herrb Date: Mon Jan 2 13:23:59 2012 +0000 Add OpenBSD support to DetermineClientCmd() Uses kvm_getargv() from libkvm. Signed-off-by: Matthieu Herrb Reviewed-by: Adam Jackson Signed-off-by: Keith Packard commit cfc4c3d7fa8bd4da4c08b2ab8e6f85435f75353a Author: Alan Coopersmith Date: Sat Dec 24 10:00:56 2011 -0800 Add Solaris support to DetermineClientCmd Uses /proc/pid/psinfo to read command & partial arguments. Moves cmdsize & argsize variables into non-Solaris #else clause to avoid unused variable warnings. Fixes format mismatch errors when building with DEBUG defined on a 64-bit platform (where Mask is defined as CARD32). Signed-off-by: Alan Coopersmith Reviewed-by: Rami Ylimäki Signed-off-by: Keith Packard commit 780133f9ae7fada462714b47e79d26075bbd9abe Author: Alan Coopersmith Date: Fri Oct 28 21:29:50 2011 -0700 Convert DetermineClientCmd to use strdup instead of malloc+strncpy *cmdname is initialized to NULL earlier in the function, so it's okay to overwrite it with NULL if strdup fails, don't need that extra check. Signed-off-by: Alan Coopersmith Reviewed-by: Jeremy Huddleston commit 2ef4ff45ef1fcfc4967ebe3d550408769e5f6500 Author: Erkki Seppälä Date: Fri Mar 25 10:38:23 2011 +0200 os/client: Prevent rare fd leak in DetermineClientPid DetermineClientPid didn't close file descriptor if read on /proc/pid/cmdline failed. Adjusted the code to disregard the close return value and perform the return after that, if the read failed or returned EOF. Signed-off-by: Mark Kettenis Signed-off-by: Erkki Seppälä Reviewed-by: Rami Ylimäki Signed-off-by: Keith Packard commit 1e933665bef26c74196bb7c59910e6a78bcacf0e Author: Rami Ylimäki Date: Wed Dec 22 16:51:09 2010 +0200 os: Add facilities for client ID tracking. An interface is provided for figuring out the PID and process name of a client. Make some existing functionality from SELinux and IA extensions available for general use. Signed-off-by: Rami Ylimäki Reviewed-by: Tiago Vignatti Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/Imakefile | 9 + nx-X11/programs/Xserver/dix/dispatch.c | 10 + nx-X11/programs/Xserver/dix/main.c | 3 + nx-X11/programs/Xserver/include/Imakefile | 1 + nx-X11/programs/Xserver/include/client.h | 60 +++++ nx-X11/programs/Xserver/include/dixstruct.h | 3 + nx-X11/programs/Xserver/os/Imakefile | 2 + nx-X11/programs/Xserver/os/client.c | 397 ++++++++++++++++++++++++++++ 8 files changed, 485 insertions(+) create mode 100644 nx-X11/programs/Xserver/include/client.h create mode 100644 nx-X11/programs/Xserver/os/client.c diff --git a/nx-X11/programs/Xserver/Imakefile b/nx-X11/programs/Xserver/Imakefile index 2af91821d..745b26154 100644 --- a/nx-X11/programs/Xserver/Imakefile +++ b/nx-X11/programs/Xserver/Imakefile @@ -323,6 +323,15 @@ NXAGENTNXLIBS = -L../../../nxcomp \ -lXcompshad \ -lXrender -lXfixes -lXfont -lXcomposite -lXdmcp \ -lNX_X11 -lXext +#elif defined(OpenBSDArchitecture) +NXAGENTNXLIBS = -L../../../nxcomp \ + -L../../../nx-X11/exports/lib \ + -L../../../nxcompshad \ + -lkvm \ + -lXcomp \ + -lXcompshad \ + -lXrender -lXfixes -lXfont -lXcomposite -lXinerama -lXdmcp \ + -lNX_X11 -lXext #else NXAGENTNXLIBS = -L../../../nxcomp \ -L../../../nx-X11/exports/lib \ diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index 3869ef723..16b94301f 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -112,6 +112,7 @@ int ProcInitialConnection(); #include "inputstr.h" #include "xkbsrv.h" #endif +#include "client.h" #define mskcnt ((MAXCLIENTS + 31) / 32) #define BITMASK(i) (1U << ((i) & 31)) @@ -3560,6 +3561,9 @@ CloseDownClient(register ClientPtr client) CallCallbacks((&ClientStateCallback), (void *)&clientinfo); } FreeClientResources(client); + /* Disable client ID tracking. This must be done after + * ClientStateCallback. */ + ReleaseClientIds(client); if (client->index < nextFreeClientID) nextFreeClientID = client->index; clients[client->index] = NullClient; @@ -3643,6 +3647,7 @@ void InitClient(ClientPtr client, int i, void * ospriv) client->smart_start_tick = SmartScheduleTime; client->smart_stop_tick = SmartScheduleTime; client->smart_check_tick = SmartScheduleTime; + client->clientIds = NULL; } extern int clientPrivateLen; @@ -3724,6 +3729,11 @@ ClientPtr NextAvailableClient(void * ospriv) currentMaxClients++; while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) nextFreeClientID++; + + /* Enable client ID tracking. This must be done before + * ClientStateCallback. */ + ReserveClientIds(client); + if (ClientStateCallback) { NewClientInfoRec clientinfo; diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index 7bd41d865..50bbeb3dc 100644 --- a/nx-X11/programs/Xserver/dix/main.c +++ b/nx-X11/programs/Xserver/dix/main.c @@ -100,6 +100,7 @@ Equipment Corporation. #include "site.h" #include "dixfont.h" #include "extnsionst.h" +#include "client.h" #ifdef PANORAMIX #include "panoramiXsrv.h" #else @@ -382,6 +383,7 @@ main(int argc, char *argv[], char *envp[]) InitInput(argc, argv); if (InitAndStartDevices() != Success) FatalError("failed to initialize core devices"); + ReserveClientIds(serverClient); InitFonts(); if (loadableFonts) { @@ -470,6 +472,7 @@ main(int argc, char *argv[], char *envp[]) #endif FreeAuditTimer(); + ReleaseClientIds(serverClient); free(serverClient->devPrivates); serverClient->devPrivates = NULL; diff --git a/nx-X11/programs/Xserver/include/Imakefile b/nx-X11/programs/Xserver/include/Imakefile index d1d7bd651..53f193ec8 100644 --- a/nx-X11/programs/Xserver/include/Imakefile +++ b/nx-X11/programs/Xserver/include/Imakefile @@ -16,6 +16,7 @@ depend:: InstallDriverSDKNonExecFile(XIstubs.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(bstore.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(bstorestr.h,$(DRIVERSDKINCLUDEDIR)) +InstallDriverSDKNonExecFile(client.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(colormap.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(colormapst.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(cursor.h,$(DRIVERSDKINCLUDEDIR)) diff --git a/nx-X11/programs/Xserver/include/client.h b/nx-X11/programs/Xserver/include/client.h new file mode 100644 index 000000000..87f2b1172 --- /dev/null +++ b/nx-X11/programs/Xserver/include/client.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All + * rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* Author: Rami Ylimäki */ + +#ifndef CLIENT_H +#define CLIENT_H + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif /* HAVE_DIX_CONFIG_H */ +#include +#include + +/* Client IDs. Use GetClientPid, GetClientCmdName and GetClientCmdArgs + * instead of accessing the fields directly. */ +typedef struct { + pid_t pid; /* process ID, -1 if not available */ + const char *cmdname; /* process name, NULL if not available */ + const char *cmdargs; /* process arguments, NULL if not available */ +} ClientIdRec, *ClientIdPtr; + +struct _Client; + +/* Initialize and clean up. */ +void ReserveClientIds(struct _Client *client); +void ReleaseClientIds(struct _Client *client); + +/* Determine client IDs for caching. Exported on purpose for + * extensions such as SELinux. */ +extern _X_EXPORT pid_t DetermineClientPid(struct _Client *client); +extern _X_EXPORT void DetermineClientCmd(pid_t, const char **cmdname, + const char **cmdargs); + +/* Query cached client IDs. Exported on purpose for drivers. */ +extern _X_EXPORT pid_t GetClientPid(struct _Client *client); +extern _X_EXPORT const char *GetClientCmdName(struct _Client *client); +extern _X_EXPORT const char *GetClientCmdArgs(struct _Client *client); + +#endif /* CLIENT_H */ diff --git a/nx-X11/programs/Xserver/include/dixstruct.h b/nx-X11/programs/Xserver/include/dixstruct.h index 1096f5c40..b8ee8e9cf 100644 --- a/nx-X11/programs/Xserver/include/dixstruct.h +++ b/nx-X11/programs/Xserver/include/dixstruct.h @@ -24,6 +24,7 @@ SOFTWARE. #ifndef DIXSTRUCT_H #define DIXSTRUCT_H +#include "client.h" #include "dix.h" #include "resource.h" #include "cursor.h" @@ -141,6 +142,8 @@ typedef struct _Client { long smart_start_tick; long smart_stop_tick; long smart_check_tick; + + ClientIdPtr clientIds; } ClientRec; /* diff --git a/nx-X11/programs/Xserver/os/Imakefile b/nx-X11/programs/Xserver/os/Imakefile index 144cb5a55..86f5cd4e6 100644 --- a/nx-X11/programs/Xserver/os/Imakefile +++ b/nx-X11/programs/Xserver/os/Imakefile @@ -128,6 +128,7 @@ TMEMCMP_OBJS = timingsafe_memcmp.o BOOTSTRAPCFLAGS = SRCS = WaitFor.c \ access.c \ + client.c \ connection.c \ io.c \ $(COLOR_SRCS) \ @@ -151,6 +152,7 @@ BOOTSTRAPCFLAGS = OBJS = WaitFor.o \ access.o \ + client.o \ connection.o \ io.o \ $(COLOR_OBJS) \ diff --git a/nx-X11/programs/Xserver/os/client.c b/nx-X11/programs/Xserver/os/client.c new file mode 100644 index 000000000..ef5e3935d --- /dev/null +++ b/nx-X11/programs/Xserver/os/client.c @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). All + * rights reserved. + * Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * @file + * + * This file contains functionality for identifying clients by various + * means. The primary purpose of identification is to simply aid in + * finding out which clients are using X server and how they are using + * it. For example, it's often necessary to monitor what requests + * clients are executing (to spot bad behaviour) and how they are + * allocating resources in X server (to spot excessive resource + * usage). + * + * This framework automatically allocates information, that can be + * used for client identification, when a client connects to the + * server. The information is freed when the client disconnects. The + * allocated information is just a collection of various IDs, such as + * PID and process name for local clients, that are likely to be + * useful in analyzing X server usage. + * + * Users of the framework can query ID information about clients at + * any time. To avoid repeated polling of IDs the users can also + * subscribe for notifications about the availability of ID + * information. IDs have been allocated before ClientStateCallback is + * called with ClientStateInitial state. Similarly the IDs will be + * released after ClientStateCallback is called with ClientStateGone + * state. + * + * Author: Rami Ylimäki + */ + +#include +#include +#include + +#include "client.h" +#include "os.h" +#include "dixstruct.h" + +#ifdef __sun +#include +#include +#endif + +#ifdef __OpenBSD__ +#include +#include +#include + +#include +#include +#endif + +/** + * Try to determine a PID for a client from its connection + * information. This should be called only once when new client has + * connected, use GetClientPid to determine the PID at other times. + * + * @param[in] client Connection linked to some process. + * + * @return PID of the client. Error (-1) if PID can't be determined + * for the client. + * + * @see GetClientPid + */ +pid_t +DetermineClientPid(struct _Client * client) +{ + LocalClientCredRec *lcc = NULL; + pid_t pid = -1; + + if (client == NullClient) + return pid; + + if (client == serverClient) + return getpid(); + + if (GetLocalClientCreds(client, &lcc) != -1) { + if (lcc->fieldsSet & LCC_PID_SET) + pid = lcc->pid; + FreeLocalClientCreds(lcc); + } + + return pid; +} + +/** + * Try to determine a command line string for a client based on its + * PID. Note that mapping PID to a command hasn't been implemented for + * some operating systems. This should be called only once when a new + * client has connected, use GetClientCmdName/Args to determine the + * string at other times. + * + * @param[in] pid Process ID of a client. + + * @param[out] cmdname Client process name without arguments. You must + * release this by calling free. On error NULL is + * returned. Pass NULL if you aren't interested in + * this value. + * @param[out] cmdargs Arguments to client process. Useful for + * identifying a client that is executed from a + * launcher program. You must release this by + * calling free. On error NULL is returned. Pass + * NULL if you aren't interested in this value. + * + * @see GetClientCmdName/Args + */ +void +DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs) +{ + char path[PATH_MAX + 1]; + int totsize = 0; + int fd = 0; + + if (cmdname) + *cmdname = NULL; + if (cmdargs) + *cmdargs = NULL; + + if (pid == -1) + return; + +#ifdef __sun /* Solaris */ + /* Solaris does not support /proc/pid/cmdline, but makes information + * similar to what ps shows available in a binary structure in the + * /proc/pid/psinfo file. */ + if (snprintf(path, sizeof(path), "/proc/%d/psinfo", pid) < 0) + return; + fd = open(path, O_RDONLY); + if (fd < 0) { + ErrorF("Failed to open %s: %s\n", path, strerror(errno)); + return; + } + else { + psinfo_t psinfo = { 0 }; + char *sp; + + totsize = read(fd, &psinfo, sizeof(psinfo_t)); + close(fd); + if (totsize <= 0) + return; + + /* pr_psargs is the first PRARGSZ (80) characters of the command + * line string - assume up to the first space is the command name, + * since it's not delimited. While there is also pr_fname, that's + * more limited, giving only the first 16 chars of the basename of + * the file that was exec'ed, thus cutting off many long gnome + * command names, or returning "isapython2.6" for all python scripts. + */ + psinfo.pr_psargs[PRARGSZ - 1] = '\0'; + sp = strchr(psinfo.pr_psargs, ' '); + if (sp) + *sp++ = '\0'; + + if (cmdname) + *cmdname = strdup(psinfo.pr_psargs); + + if (cmdargs && sp) + *cmdargs = strdup(sp); + } +#elif defined(__OpenBSD__) + /* on OpenBSD use kvm_getargv() */ + { + kvm_t *kd; + char errbuf[_POSIX2_LINE_MAX]; + char **argv; + struct kinfo_proc *kp; + size_t len = 0; + int i, n; + + kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + if (kd == NULL) + return; + kp = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), + &n); + if (n != 1) + return; + argv = kvm_getargv(kd, kp, 0); + *cmdname = strdup(argv[0]); + i = 1; + while (argv[i] != NULL) { + len += strlen(argv[i]) + 1; + i++; + } + *cmdargs = calloc(1, len); + i = 1; + while (argv[i] != NULL) { + strlcat(*cmdargs, argv[i], len); + strlcat(*cmdargs, " ", len); + i++; + } + kvm_close(kd); + } +#else /* Linux using /proc/pid/cmdline */ + + /* Check if /proc/pid/cmdline exists. It's not supported on all + * operating systems. */ + if (snprintf(path, sizeof(path), "/proc/%d/cmdline", pid) < 0) + return; + fd = open(path, O_RDONLY); + if (fd < 0) + return; + + /* Read the contents of /proc/pid/cmdline. It should contain the + * process name and arguments. */ + totsize = read(fd, path, sizeof(path)); + close(fd); + if (totsize <= 0) + return; + path[totsize - 1] = '\0'; + + /* Contruct the process name without arguments. */ + if (cmdname) { + *cmdname = strdup(path); + } + + /* Construct the arguments for client process. */ + if (cmdargs) { + int cmdsize = strlen(path) + 1; + int argsize = totsize - cmdsize; + char *args = NULL; + + if (argsize > 0) + args = malloc(argsize); + if (args) { + int i = 0; + + for (i = 0; i < (argsize - 1); ++i) { + const char c = path[cmdsize + i]; + + args[i] = (c == '\0') ? ' ' : c; + } + args[argsize - 1] = '\0'; + *cmdargs = args; + } + } +#endif +} + +/** + * Called when a new client connects. Allocates client ID information. + * + * @param[in] client Recently connected client. + */ +void +ReserveClientIds(struct _Client *client) +{ +#ifdef CLIENTIDS + if (client == NullClient) + return; + + assert(!client->clientIds); + client->clientIds = calloc(1, sizeof(ClientIdRec)); + if (!client->clientIds) + return; + + client->clientIds->pid = DetermineClientPid(client); + if (client->clientIds->pid != -1) + DetermineClientCmd(client->clientIds->pid, &client->clientIds->cmdname, + &client->clientIds->cmdargs); + + DebugF("client(%lx): Reserved pid(%d).\n", + (unsigned long) client->clientAsMask, client->clientIds->pid); + DebugF("client(%lx): Reserved cmdname(%s) and cmdargs(%s).\n", + (unsigned long) client->clientAsMask, + client->clientIds->cmdname ? client->clientIds->cmdname : "NULL", + client->clientIds->cmdargs ? client->clientIds->cmdargs : "NULL"); +#endif /* CLIENTIDS */ +} + +/** + * Called when an existing client disconnects. Frees client ID + * information. + * + * @param[in] client Recently disconnected client. + */ +void +ReleaseClientIds(struct _Client *client) +{ +#ifdef CLIENTIDS + if (client == NullClient) + return; + + if (!client->clientIds) + return; + + DebugF("client(%lx): Released pid(%d).\n", + (unsigned long) client->clientAsMask, client->clientIds->pid); + DebugF("client(%lx): Released cmdline(%s) and cmdargs(%s).\n", + (unsigned long) client->clientAsMask, + client->clientIds->cmdname ? client->clientIds->cmdname : "NULL", + client->clientIds->cmdargs ? client->clientIds->cmdargs : "NULL"); + + free((void *) client->clientIds->cmdname); /* const char * */ + free((void *) client->clientIds->cmdargs); /* const char * */ + free(client->clientIds); + client->clientIds = NULL; +#endif /* CLIENTIDS */ +} + +/** + * Get cached PID of a client. + * + * param[in] client Client whose PID has been already cached. + * + * @return Cached client PID. Error (-1) if called: + * - before ClientStateInitial client state notification + * - after ClientStateGone client state notification + * - for remote clients + * + * @see DetermineClientPid + */ +pid_t +GetClientPid(struct _Client *client) +{ + if (client == NullClient) + return -1; + + if (!client->clientIds) + return -1; + + return client->clientIds->pid; +} + +/** + * Get cached command name string of a client. + * + * param[in] client Client whose command line string has been already + * cached. + * + * @return Cached client command name. Error (NULL) if called: + * - before ClientStateInitial client state notification + * - after ClientStateGone client state notification + * - for remote clients + * - on OS that doesn't support mapping of PID to command line + * + * @see DetermineClientCmd + */ +const char * +GetClientCmdName(struct _Client *client) +{ + if (client == NullClient) + return NULL; + + if (!client->clientIds) + return NULL; + + return client->clientIds->cmdname; +} + +/** + * Get cached command arguments string of a client. + * + * param[in] client Client whose command line string has been already + * cached. + * + * @return Cached client command arguments. Error (NULL) if called: + * - before ClientStateInitial client state notification + * - after ClientStateGone client state notification + * - for remote clients + * - on OS that doesn't support mapping of PID to command line + * + * @see DetermineClientCmd + */ +const char * +GetClientCmdArgs(struct _Client *client) +{ + if (client == NullClient) + return NULL; + + if (!client->clientIds) + return NULL; + + return client->clientIds->cmdargs; +} -- cgit v1.2.3 From 349b6dec54eaa86b49f3627939c4e7039e3b25f0 Mon Sep 17 00:00:00 2001 From: Pauli Nieminen Date: Thu, 16 Feb 2017 10:35:39 +0100 Subject: os: always check if client is local when connection is accepted Backported from X.org: commit 2d67ada3c4079a11c52024a9c3d4138becca5171 Author: Pauli Nieminen Date: Thu Dec 30 19:19:43 2010 +0200 os: always check if client is local when connection is accepted LocalClient is used for all DRI2 requests that makes it frequently called function. Querying if connection is local or not takes 10-15us (on ARM) depending on malloc speed. Signed-off-by: Pauli Nieminen Reviewed-by: Daniel Stone Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/access.c | 17 ++++++++++++++--- nx-X11/programs/Xserver/os/connection.c | 1 + nx-X11/programs/Xserver/os/osdep.h | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c index d745bde3a..e9d5d8ae8 100644 --- a/nx-X11/programs/Xserver/os/access.c +++ b/nx-X11/programs/Xserver/os/access.c @@ -1217,12 +1217,17 @@ ResetHosts (char *display) } /* Is client on the local host */ -Bool LocalClient(ClientPtr client) +Bool +ComputeLocalClient(ClientPtr client) { int alen, family, notused; Xtransaddr *from = NULL; void *addr; register HOST *host; + OsCommPtr oc = (OsCommPtr) client->osPrivate; + + if (!oc->trans_conn) + return FALSE; #ifdef XCSECURITY /* untrusted clients can't change host access */ @@ -1233,8 +1238,7 @@ Bool LocalClient(ClientPtr client) return FALSE; } #endif - if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn, - ¬used, &alen, &from)) + if (!_XSERVTransGetPeerAddr (oc->trans_conn, ¬used, &alen, &from)) { family = ConvertAddr ((struct sockaddr *) from, &alen, (void **)&addr); @@ -1260,6 +1264,13 @@ Bool LocalClient(ClientPtr client) return FALSE; } +Bool LocalClient(ClientPtr client) +{ + if (!client->osPrivate) + return FALSE; + return ((OsCommPtr)client->osPrivate)->local_client; +} + /* * Return the uid and gid of a connected local client * diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 538996198..cee621384 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -754,6 +754,7 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) free (oc); return NullClient; } + oc->local_client = ComputeLocalClient(client); { #if !defined(WIN32) ConnectionTranslation[fd] = client->index; diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h index dc66649dc..709f33943 100644 --- a/nx-X11/programs/Xserver/os/osdep.h +++ b/nx-X11/programs/Xserver/os/osdep.h @@ -176,6 +176,7 @@ typedef struct _osComm { XID auth_id; /* authorization id */ CARD32 conn_time; /* timestamp if not established, else 0 */ struct _XtransConnInfo *trans_conn; /* transport connection object */ + Bool local_client; } OsCommRec, *OsCommPtr; extern int FlushClient( @@ -239,6 +240,9 @@ typedef long int fd_mask; #define ffs mffs extern int mffs(fd_mask); +/* in access.c */ +extern Bool ComputeLocalClient(ClientPtr client); + /* in auth.c */ extern void GenerateRandomData (int len, char *buf); -- cgit v1.2.3 From ed52cb2952bebf6b98e187ff1f8609690fae3d59 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 16 Feb 2017 10:51:40 +0000 Subject: dix: Pull client-is-local flag up to the ClientRec Backported from X.org commit ff8e3ad8074cd2c8bed49b39c40c2b4892118270 Author: Adam Jackson Date: Thu Sep 20 13:16:59 2012 -0400 dix: Pull client-is-local flag up to the ClientRec Reviewed-by: Daniel Stone Signed-off-by: Adam Jackson Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/Xext/xf86bigfont.c | 4 ++-- nx-X11/programs/Xserver/include/dixstruct.h | 1 + nx-X11/programs/Xserver/include/os.h | 2 -- nx-X11/programs/Xserver/os/access.c | 9 +-------- nx-X11/programs/Xserver/os/connection.c | 2 +- nx-X11/programs/Xserver/os/osdep.h | 1 - 6 files changed, 5 insertions(+), 14 deletions(-) diff --git a/nx-X11/programs/Xserver/Xext/xf86bigfont.c b/nx-X11/programs/Xserver/Xext/xf86bigfont.c index 107b0f23f..4c8f02c2c 100644 --- a/nx-X11/programs/Xserver/Xext/xf86bigfont.c +++ b/nx-X11/programs/Xserver/Xext/xf86bigfont.c @@ -366,7 +366,7 @@ ProcXF86BigfontQueryVersion( #endif reply.capabilities = #ifdef HAS_SHM - (LocalClient(client) && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0) + (client->local && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0) #else 0 #endif @@ -430,7 +430,7 @@ ProcXF86BigfontQueryFont( #else switch (client->req_len) { case 2: /* client with version 1.0 libX11 */ - stuff_flags = (LocalClient(client) && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0); + stuff_flags = (client->local && !client->swapped ? XF86Bigfont_FLAGS_Shm : 0); break; case 3: /* client with version 1.1 libX11 */ stuff_flags = stuff->flags; diff --git a/nx-X11/programs/Xserver/include/dixstruct.h b/nx-X11/programs/Xserver/include/dixstruct.h index b8ee8e9cf..cdd2543a6 100644 --- a/nx-X11/programs/Xserver/include/dixstruct.h +++ b/nx-X11/programs/Xserver/include/dixstruct.h @@ -95,6 +95,7 @@ typedef struct _Client { void *requestBuffer; void *osPrivate; /* for OS layer, including scheduler */ Bool swapped; + Bool local; ReplySwapPtr pSwapReplyFunc; XID errorValue; int sequence; diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index af84f54c0..5de8463e7 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -317,8 +317,6 @@ typedef struct sockaddr * sockaddrPtr; extern int InvalidHost(sockaddrPtr /*saddr*/, int /*len*/, ClientPtr client); -extern int LocalClient(ClientPtr /* client */); - extern int LocalClientCred(ClientPtr, int *, int *); #define LCC_UID_SET (1 << 0) diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c index e9d5d8ae8..d8d035ade 100644 --- a/nx-X11/programs/Xserver/os/access.c +++ b/nx-X11/programs/Xserver/os/access.c @@ -1264,13 +1264,6 @@ ComputeLocalClient(ClientPtr client) return FALSE; } -Bool LocalClient(ClientPtr client) -{ - if (!client->osPrivate) - return FALSE; - return ((OsCommPtr)client->osPrivate)->local_client; -} - /* * Return the uid and gid of a connected local client * @@ -1419,7 +1412,7 @@ AuthorizedClient(ClientPtr client) { if (!client || defeatAccessControl) return TRUE; - return LocalClient(client); + return client->local ? Success : BadAccess; } /* Add a host to the access control list. This is the external interface diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index cee621384..917f79fa6 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -754,7 +754,7 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) free (oc); return NullClient; } - oc->local_client = ComputeLocalClient(client); + client->local = ComputeLocalClient(client); { #if !defined(WIN32) ConnectionTranslation[fd] = client->index; diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h index 709f33943..fdd8c7174 100644 --- a/nx-X11/programs/Xserver/os/osdep.h +++ b/nx-X11/programs/Xserver/os/osdep.h @@ -176,7 +176,6 @@ typedef struct _osComm { XID auth_id; /* authorization id */ CARD32 conn_time; /* timestamp if not established, else 0 */ struct _XtransConnInfo *trans_conn; /* transport connection object */ - Bool local_client; } OsCommRec, *OsCommPtr; extern int FlushClient( -- cgit v1.2.3 From 4f76ed19b8a7b9448e29ac152f7f5ec1e611950e Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 16 Feb 2017 10:54:19 +0000 Subject: dix: Extend initial connection handshake for forwarding proxies commit 78fa121f4097d29458e5453c13473595df06e26e Author: Adam Jackson Date: Fri Jun 17 13:43:38 2011 -0400 dix: Extend initial connection handshake for forwarding proxies Forwarding proxies like sshd will appear to be local, even though they aren't really. This leads to weird behaviour for extensions that truly require running under the same OS services as the client, like MIT-SHM and DRI2. Add two new legal values for the initial connection's byteOrder field, 'r' and 'R'. These act like 'l' and 'B' respectively, but have the side effect of forcing the client to be treated as non-local. Forwarding proxies should attempt to munge the first packet of the connection accordingly; older servers will reject connections thusly munged, so the proxy should fall back to passthrough if the munged connection attempt fails. Reviewed-by: Daniel Stone Signed-off-by: Adam Jackson Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/dispatch.c | 12 +++++++++--- nx-X11/programs/Xserver/os/connection.c | 10 +++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index 16b94301f..438436526 100644 --- a/nx-X11/programs/Xserver/dix/dispatch.c +++ b/nx-X11/programs/Xserver/dix/dispatch.c @@ -3752,12 +3752,14 @@ ProcInitialConnection(register ClientPtr client) REQUEST(xReq); register xConnClientPrefix *prefix; int whichbyte = 1; + char order; prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); - if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) + order = prefix->byteOrder; + if (order != 'l' && order != 'B' && order != 'r' && order != 'R') return (client->noClientException = -1); - if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || - (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) + if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || + (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) { client->swapped = TRUE; SwapConnClientPrefix(prefix); @@ -3769,6 +3771,10 @@ ProcInitialConnection(register ClientPtr client) { swaps(&stuff->length); } + if (order == 'r' || order == 'R') + { + client->local = FALSE; + } ResetCurrentRequest(client); return (client->noClientException); } diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 917f79fa6..d4627e97c 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -886,7 +886,7 @@ ErrorConnMax(XtransConnInfo trans_conn) xConnSetupPrefix csp; char pad[3]; struct iovec iov[3]; - char byteOrder = 0; + char order = 0; int whichbyte = 1; struct timeval waittime; fd_set mask; @@ -899,16 +899,16 @@ ErrorConnMax(XtransConnInfo trans_conn) FD_SET(fd, &mask); (void)Select(fd + 1, &mask, NULL, NULL, &waittime); /* try to read the byte-order of the connection */ - (void)_XSERVTransRead(trans_conn, &byteOrder, 1); - if ((byteOrder == 'l') || (byteOrder == 'B')) + (void)_XSERVTransRead(trans_conn, &order, 1); + if (order == 'l' || order == 'B' || order == 'r' || order == 'R') { 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'))) + if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) || + (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) { swaps(&csp.majorVersion); swaps(&csp.minorVersion); -- cgit v1.2.3 From f5301dee4e400698f5b8ea324686b8daba75152d Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 15 Mar 2017 12:08:46 +0100 Subject: Move SIGUSR1 notification as late as possible. commit f01e149d1af14ef9ee0e8a6743ab6a08f3bb677c Author: Adam Jackson Date: Thu Nov 1 15:41:11 2007 -0400 Move SIGUSR1 notification as late as possible. If we inherited a signal mask from the parent process that ignores SIGUSR1, then we will send SIGUSR1 to the parent to indicate when we're ready to accept connections. Unfortunately, we send this notification way too early, right after creating the sockets rather than just before entering the main loop. Move it to just before Dispatch() so we're not lying quite so much. Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/main.c | 2 + nx-X11/programs/Xserver/include/os.h | 2 + nx-X11/programs/Xserver/os/connection.c | 87 +++++++++++++++++++-------------- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index 50bbeb3dc..72ed40108 100644 --- a/nx-X11/programs/Xserver/dix/main.c +++ b/nx-X11/programs/Xserver/dix/main.c @@ -432,6 +432,8 @@ main(int argc, char *argv[], char *envp[]) FatalError("could not create connection block info"); } + NotifyParentProcess(); + Dispatch(); /* Now free up whatever must be freed */ diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index 5de8463e7..5dd5e2012 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -120,6 +120,8 @@ extern void ResetOsBuffers(void); extern void InitConnectionLimits(void); +extern void NotifyParentProcess(void); + extern void CreateWellKnownSockets(void); extern void ResetWellKnownSockets(void); diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index d4627e97c..172ed6f4c 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -319,6 +319,52 @@ InitConnectionLimits(void) #endif } +/* + * If SIGUSR1 was set to SIG_IGN when the server started, assume that either + * + * a- The parent process is ignoring SIGUSR1 + * + * or + * + * b- The parent process is expecting a SIGUSR1 + * when the server is ready to accept connections + * + * In the first case, the signal will be harmless, in the second case, + * the signal will be quite useful. + */ +static void +InitParentProcess(void) +{ +#if !defined(WIN32) + OsSigHandlerPtr handler; + handler = OsSignal (SIGUSR1, SIG_IGN); + if ( handler == SIG_IGN) + RunFromSmartParent = TRUE; + OsSignal(SIGUSR1, handler); + ParentProcess = getppid (); +#ifdef __UNIXOS2__ + /* + * fg030505: under OS/2, xinit is not the parent process but + * the "grant parent" process of the server because execvpe() + * presents us an additional process number; + * GetPPID(pid) is part of libemxfix + */ + ParentProcess = GetPPID (ParentProcess); +#endif /* __UNIXOS2__ */ +#endif +} + +void +NotifyParentProcess(void) +{ +#if !defined(WIN32) + if (RunFromSmartParent) { + if (ParentProcess > 1) { + kill (ParentProcess, SIGUSR1); + } + } +#endif +} /***************** * CreateWellKnownSockets @@ -331,7 +377,6 @@ CreateWellKnownSockets(void) int i; int partial; char port[20]; - OsSigHandlerPtr handler; FD_ZERO(&AllSockets); FD_ZERO(&AllClients); @@ -385,33 +430,9 @@ CreateWellKnownSockets(void) OsSignal (SIGTERM, GiveUp); XFD_COPYSET (&WellKnownConnections, &AllSockets); ResetHosts(display); - /* - * Magic: If SIGUSR1 was set to SIG_IGN when - * the server started, assume that either - * - * a- The parent process is ignoring SIGUSR1 - * - * or - * - * b- The parent process is expecting a SIGUSR1 - * when the server is ready to accept connections - * - * In the first case, the signal will be harmless, - * in the second case, the signal will be quite - * useful - */ -#if !defined(WIN32) - handler = OsSignal (SIGUSR1, SIG_IGN); - if ( handler == SIG_IGN) - RunFromSmartParent = TRUE; - OsSignal(SIGUSR1, handler); - ParentProcess = getppid (); - if (RunFromSmartParent) { - if (ParentProcess > 1) { - kill (ParentProcess, SIGUSR1); - } - } -#endif + + InitParentProcess(); + #ifdef XDMCP XdmcpInit (); #endif @@ -499,16 +520,6 @@ ResetWellKnownSockets (void) ResetAuthorization (); ResetHosts(display); - /* - * See above in CreateWellKnownSockets about SIGUSR1 - */ -#if !defined(WIN32) - if (RunFromSmartParent) { - if (ParentProcess > 1) { - kill (ParentProcess, SIGUSR1); - } - } -#endif /* * restart XDMCP */ -- cgit v1.2.3 From eb49996116fd3beeff66ddf192bfc80e117086d1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 15 Mar 2017 11:42:30 +0100 Subject: os: Use NotifyFd for ErrorConnMax commit c3fea428aed919826130ef8ebdb2cceb445a845b Author: Keith Packard Date: Tue May 24 20:51:31 2016 -0700 os: Use NotifyFd for ErrorConnMax Instead of open-coding a single FD wait, use NotifyFd to wait for the FD to become readable before returning the error message. Signed-off-by: Keith Packard Reviewed-by: Adam Jackson Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/connection.c | 36 +++++++++++++++++---------------- nx-X11/programs/Xserver/os/osdep.h | 1 - 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 172ed6f4c..2fa8ad12d 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -74,6 +74,7 @@ SOFTWARE. #define TRANS_SERVER #define TRANS_REOPEN #include +#include #include #include #include @@ -874,7 +875,6 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure) )) { ErrorConnMax(new_trans_conn); - _XSERVTransClose(new_trans_conn); } } #ifndef WIN32 @@ -891,28 +891,21 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure) ************/ static void -ErrorConnMax(XtransConnInfo trans_conn) +ConnMaxNotify(int fd, int events, void *data) { - int fd = _XSERVTransGetConnectionNumber (trans_conn); - xConnSetupPrefix csp; - char pad[3]; - struct iovec iov[3]; + XtransConnInfo trans_conn = data; char order = 0; - int whichbyte = 1; - 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); + /* try to read the byte-order of the connection */ (void)_XSERVTransRead(trans_conn, &order, 1); if (order == 'l' || order == 'B' || order == 'r' || order == 'R') { + + xConnSetupPrefix csp; + char pad[3] = { 0, 0, 0 }; + int whichbyte = 1; + struct iovec iov[3]; + csp.success = xFalse; csp.lengthReason = sizeof(NOROOM) - 1; csp.length = (sizeof(NOROOM) + 2) >> 2; @@ -933,6 +926,15 @@ ErrorConnMax(XtransConnInfo trans_conn) iov[2].iov_base = pad; (void)_XSERVTransWritev(trans_conn, iov, 3); } + RemoveNotifyFd(trans_conn->fd); + _XSERVTransClose(trans_conn); +} + +static void +ErrorConnMax(XtransConnInfo trans_conn) +{ + if (!SetNotifyFd(trans_conn->fd, ConnMaxNotify, X_NOTIFY_READ, trans_conn)) + _XSERVTransClose(trans_conn); } /************ diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h index fdd8c7174..d3e9d0b33 100644 --- a/nx-X11/programs/Xserver/os/osdep.h +++ b/nx-X11/programs/Xserver/os/osdep.h @@ -52,7 +52,6 @@ SOFTWARE. #ifndef _OSDEP_H_ #define _OSDEP_H_ 1 -#define BOTIMEOUT 200 /* in milliseconds */ #define BUFSIZE 4096 #define BUFWATERMARK 8192 #ifndef MAXBUFSIZE -- cgit v1.2.3 From 89496d987dc6a21250c9fdda2cd3668516061f5c Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Wed, 15 Mar 2017 14:10:24 +0000 Subject: os: Add -displayfd option commit 88bacc49f06da5927f716869f5a32672a8297ed0 Author: Chase Douglas Date: Wed Apr 4 15:29:42 2012 -0700 os: Add -displayfd option This option specifies a file descriptor in the launching process. X will scan for an available display number and write that number back to the launching process, at the same time as SIGUSR1 generation. This means display managers don't need to guess at available display numbers. As a consequence, if X fails to start when using -displayfd, it's not because the display was in use, so there's no point in retrying the X launch on a higher display number. Signed-off-by: Adam Jackson Signed-off-by: Chase Douglas Reviewed-by: Julien Cristau Tested-by: Julien Cristau Reviewed-by: Alan Coopersmith Signed-off-by: Peter Hutterer Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/globals.c | 1 + nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 7 +++ nx-X11/programs/Xserver/include/opaque.h | 1 + nx-X11/programs/Xserver/os/connection.c | 76 ++++++++++++++++-------- nx-X11/programs/Xserver/os/utils.c | 10 ++++ 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/globals.c b/nx-X11/programs/Xserver/dix/globals.c index a0af50fa8..5a3e22c26 100644 --- a/nx-X11/programs/Xserver/dix/globals.c +++ b/nx-X11/programs/Xserver/dix/globals.c @@ -149,6 +149,7 @@ int defaultColorVisualClass = -1; int monitorResolution = 0; char *display; +int displayfd; CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; int argcGlobal; diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index af5fc88f8..66f25b438 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -178,6 +178,13 @@ different from the user's real uid. .B \-core causes the server to generate a core dump on fatal errors. .TP 8 +.B \-displayfd \fIfd\fP +specifies a file descriptor in the launching process. Rather than specify +a display number, the X server will attempt to listen on successively higher +display numbers, and upon finding a free one, will write the port number back +on this file descriptor as a newline-terminated string. The \-pn option is +ignored when using \-displayfd. +.TP 8 .B \-deferglyphs \fIwhichfonts\fP specifies the types of fonts for which the server should attempt to use deferred glyph loading. \fIwhichfonts\fP can be all (all fonts), diff --git a/nx-X11/programs/Xserver/include/opaque.h b/nx-X11/programs/Xserver/include/opaque.h index bd286ba12..8f98bf1be 100644 --- a/nx-X11/programs/Xserver/include/opaque.h +++ b/nx-X11/programs/Xserver/include/opaque.h @@ -52,6 +52,7 @@ extern int defaultScreenSaverAllowExposures; extern int argcGlobal; extern char **argvGlobal; extern char *display; +extern int displayfd; extern int defaultBackingStore; extern Bool disableBackingStore; diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 2fa8ad12d..6dc0ff64d 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -138,6 +138,7 @@ int NumNotifyWriteFd; /* Number of NotifyFd members with write set */ Bool NewOutputPending; /* not yet attempted to write some new output */ Bool AnyWritesPending; /* true if some client blocked on write or NotifyFd with write */ Bool RunFromSmartParent; /* send SIGUSR1 to parent process */ +static char dynamic_display[7]; /* display name */ Bool PartialNetwork; /* continue even if unable to bind all addrs */ static Pid_t ParentProcess; @@ -359,6 +360,10 @@ void NotifyParentProcess(void) { #if !defined(WIN32) + if (dynamic_display[0]) { + write(displayfd, dynamic_display, strlen(dynamic_display)); + close(displayfd); + } if (RunFromSmartParent) { if (ParentProcess > 1) { kill (ParentProcess, SIGUSR1); @@ -367,6 +372,18 @@ NotifyParentProcess(void) #endif } +static Bool +TryCreateSocket(int num, int *partial) +{ + char port[20]; + + snprintf(port, sizeof(port), "%d", num); + + return (_XSERVTransMakeAllCOTSServerListeners(port, partial, + &ListenTransCount, + &ListenTransConns) >= 0); +} + /***************** * CreateWellKnownSockets * At initialization, create the sockets to listen on for new clients. @@ -377,7 +394,6 @@ CreateWellKnownSockets(void) { int i; int partial; - char port[20]; FD_ZERO(&AllSockets); FD_ZERO(&AllClients); @@ -392,33 +408,41 @@ CreateWellKnownSockets(void) FD_ZERO (&WellKnownConnections); - sprintf (port, "%d", atoi (display)); - - if ((_XSERVTransMakeAllCOTSServerListeners (port, &partial, - &ListenTransCount, &ListenTransConns) >= 0) && - (ListenTransCount >= 1)) - { - if (!PartialNetwork && partial) - { - FatalError ("Failed to establish all listening sockets"); - } - else - { - ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int)); - - for (i = 0; i < ListenTransCount; i++) - { - int fd = _XSERVTransGetConnectionNumber (ListenTransConns[i]); - - ListenTransFds[i] = fd; - FD_SET (fd, &WellKnownConnections); - - if (!_XSERVTransIsLocal (ListenTransConns[i])) - { - DefineSelf (fd); - } + /* display is initialized to "0" by main(). It is then set to the display + * number if specified on the command line, or to NULL when the -displayfd + * option is used. */ + if (display) { + if (TryCreateSocket(atoi(display), &partial) && + ListenTransCount >= 1) + if (!PartialNetwork && partial) + FatalError ("Failed to establish all listening sockets"); + } + else { /* -displayfd */ + Bool found = 0; + for (i = 0; i < 65535 - X_TCP_PORT; i++) { + if (TryCreateSocket(i, &partial) && !partial) { + found = 1; + break; } + else + CloseWellKnownConnections(); } + if (!found) + FatalError("Failed to find a socket to listen on"); + snprintf(dynamic_display, sizeof(dynamic_display), "%d", i); + display = dynamic_display; + } + + ListenTransFds = malloc(ListenTransCount * sizeof (int)); + + for (i = 0; i < ListenTransCount; i++) { + int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]); + + ListenTransFds[i] = fd; + FD_SET(fd, &WellKnownConnections); + + if (!_XSERVTransIsLocal(ListenTransConns[i])) + DefineSelf (fd); } if (!XFD_ANYSET (&WellKnownConnections)) diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index 25cbb1e87..929549168 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -780,6 +780,16 @@ ProcessCommandLine(int argc, char *argv[]) else UseMsg(); } + else if (strcmp(argv[i], "-displayfd") == 0) { + if (++i < argc) { + displayfd = atoi(argv[i]); + display = NULL; + nolock = TRUE; + } + else + UseMsg(); + } + #ifdef DPMSExtension else if ( strcmp( argv[i], "dpms") == 0) DPMSEnabledSwitch = TRUE; -- cgit v1.2.3 From e8bc4c7e2f42d21e41328b68d5dc2a15db73d47a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 15 Mar 2017 14:56:17 +0000 Subject: os: Add a mechanism to prevent creating any listen sockets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit 44fe1b8ea284df6bbaef67e246016d104665b2fe Author: Kristian Høgsberg Date: Wed Mar 19 14:03:13 2014 -0700 os: Add a mechanism to prevent creating any listen sockets A socket-activated server will receive its listening sockets from the parent process and should not create its own sockets. This patch introduces a NoListen flag that can be set by a DDX to prevent the server from creating the sockets. When NoListen is enabled, we also disable the server lock checking, since the parent process is responsible for checking the lock before picking the display name and creating the sockets. Signed-off-by: Kristian Høgsberg Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/opaque.h | 2 +- nx-X11/programs/Xserver/os/connection.c | 8 ++++++-- nx-X11/programs/Xserver/os/utils.c | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/nx-X11/programs/Xserver/include/opaque.h b/nx-X11/programs/Xserver/include/opaque.h index 8f98bf1be..1b84b9f5b 100644 --- a/nx-X11/programs/Xserver/include/opaque.h +++ b/nx-X11/programs/Xserver/include/opaque.h @@ -77,6 +77,6 @@ extern long maxBigRequestSize; extern Bool blackRoot; extern Bool CoreDump; - +extern Bool NoListenAll; #endif /* OPAQUE_H */ diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 6dc0ff64d..8958c47b5 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -137,6 +137,7 @@ int MaxClients = 0; int NumNotifyWriteFd; /* Number of NotifyFd members with write set */ Bool NewOutputPending; /* not yet attempted to write some new output */ Bool AnyWritesPending; /* true if some client blocked on write or NotifyFd with write */ +Bool NoListenAll; /* Don't establish any listening sockets */ Bool RunFromSmartParent; /* send SIGUSR1 to parent process */ static char dynamic_display[7]; /* display name */ Bool PartialNetwork; /* continue even if unable to bind all addrs */ @@ -411,7 +412,10 @@ CreateWellKnownSockets(void) /* display is initialized to "0" by main(). It is then set to the display * number if specified on the command line, or to NULL when the -displayfd * option is used. */ - if (display) { + if (NoListenAll) { + ListenTransCount = 0; + } + else if (display) { if (TryCreateSocket(atoi(display), &partial) && ListenTransCount >= 1) if (!PartialNetwork && partial) @@ -445,7 +449,7 @@ CreateWellKnownSockets(void) DefineSelf (fd); } - if (!XFD_ANYSET (&WellKnownConnections)) + if (!XFD_ANYSET (&WellKnownConnections) && !NoListenAll) FatalError ("Cannot establish any listening sockets - Make sure an X server isn't already running"); #if !defined(WIN32) OsSignal (SIGPIPE, SIG_IGN); diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index 929549168..74acb53ef 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -338,7 +338,7 @@ LockServer(void) int len; char port[20]; - if (nolock) return; + if (nolock || NoListenAll) return; /* * Path names */ @@ -464,7 +464,7 @@ LockServer(void) void UnlockServer(void) { - if (nolock) return; + if (nolock || NoListenAll) return; if (!StillLocking){ -- cgit v1.2.3 From 506aedbcd3f56cf255b397f1e586f16f97e3619a Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Wed, 15 Mar 2017 15:00:27 +0000 Subject: Xserver/os/utils.c: Add NXAGENT_SERVER specific -nolisten parameter: ANY. This allows us to trigger the NoListenAll := TRUE code path in nxagent. --- nx-X11/programs/Xserver/os/Imakefile | 1 + nx-X11/programs/Xserver/os/utils.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/nx-X11/programs/Xserver/os/Imakefile b/nx-X11/programs/Xserver/os/Imakefile index 86f5cd4e6..7932e32cd 100644 --- a/nx-X11/programs/Xserver/os/Imakefile +++ b/nx-X11/programs/Xserver/os/Imakefile @@ -43,6 +43,7 @@ NX_DEFINES = -DNX_TRANS_SOCKET \ -DNX_TRANS_SLEEP \ -DNX_TRANS_EXIT \ -DNX_TRANS_WAKEUP=1000 \ + -DNXAGENT_SERVER \ $(NULL) # -DNX_TRANS_WARN \ diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index 74acb53ef..dce04e942 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -902,6 +902,11 @@ ProcessCommandLine(int argc, char *argv[]) else if ( strcmp( argv[i], "-nolisten") == 0) { if(++i < argc) { +#ifdef NXAGENT_SERVER + if (strcmp( argv[i], "ANY" ) == 0) + NoListenAll = TRUE; + else +#endif /* NXAGENT_SERVER */ if (_XSERVTransNoListen(argv[i])) FatalError ("Failed to disable listen for %s transport", argv[i]); -- cgit v1.2.3 From 3be144ffde5f35df21ad115cbdedb8a072420edb Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 15 Mar 2017 15:05:18 +0000 Subject: Handle -displayfd and an explicit display number sensibly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit bc348bd2c42f3f18786085ccef2f010eff5bf3d2 Author: Jon TURNEY Date: Mon Mar 11 14:34:32 2013 +0000 Handle -displayfd and an explicit display number sensibly Handle -displayfd and an explicit display number sensibly, e.g. use the explicitly specified display number, and write it to the displayfd v2: displayfd might be 0, so use -1 as invalid value v3: Rebase for addition of NoListenAll flag Signed-off-by: Jon TURNEY Reviewed-by: Kristian Høgsberg Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/dix/globals.c | 3 ++- nx-X11/programs/Xserver/include/opaque.h | 1 + nx-X11/programs/Xserver/os/connection.c | 11 +++++------ nx-X11/programs/Xserver/os/utils.c | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/nx-X11/programs/Xserver/dix/globals.c b/nx-X11/programs/Xserver/dix/globals.c index 5a3e22c26..f9fa544ed 100644 --- a/nx-X11/programs/Xserver/dix/globals.c +++ b/nx-X11/programs/Xserver/dix/globals.c @@ -149,7 +149,8 @@ int defaultColorVisualClass = -1; int monitorResolution = 0; char *display; -int displayfd; +int displayfd = -1; +Bool explicit_display = FALSE; CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; int argcGlobal; diff --git a/nx-X11/programs/Xserver/include/opaque.h b/nx-X11/programs/Xserver/include/opaque.h index 1b84b9f5b..8312b4a21 100644 --- a/nx-X11/programs/Xserver/include/opaque.h +++ b/nx-X11/programs/Xserver/include/opaque.h @@ -53,6 +53,7 @@ extern int argcGlobal; extern char **argvGlobal; extern char *display; extern int displayfd; +extern Bool explicit_display; extern int defaultBackingStore; extern Bool disableBackingStore; diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 8958c47b5..7638cdfdd 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -361,8 +361,8 @@ void NotifyParentProcess(void) { #if !defined(WIN32) - if (dynamic_display[0]) { - write(displayfd, dynamic_display, strlen(dynamic_display)); + if (displayfd >= 0) { + write(displayfd, display, strlen(display)); close(displayfd); } if (RunFromSmartParent) { @@ -410,18 +410,17 @@ CreateWellKnownSockets(void) FD_ZERO (&WellKnownConnections); /* display is initialized to "0" by main(). It is then set to the display - * number if specified on the command line, or to NULL when the -displayfd - * option is used. */ + * number if specified on the command line. */ if (NoListenAll) { ListenTransCount = 0; } - else if (display) { + else if ((displayfd < 0) || explicit_display) { if (TryCreateSocket(atoi(display), &partial) && ListenTransCount >= 1) if (!PartialNetwork && partial) FatalError ("Failed to establish all listening sockets"); } - else { /* -displayfd */ + else { /* -displayfd and no explicit display number */ Bool found = 0; for (i = 0; i < 65535 - X_TCP_PORT; i++) { if (TryCreateSocket(i, &partial) && !partial) { diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index dce04e942..6995d05d5 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -704,6 +704,7 @@ ProcessCommandLine(int argc, char *argv[]) { /* initialize display */ display = argv[i]; + explicit_display = TRUE; display++; if( ! VerifyDisplayName( display ) ) { ErrorF("Bad display name: %s\n", display); @@ -783,7 +784,6 @@ ProcessCommandLine(int argc, char *argv[]) else if (strcmp(argv[i], "-displayfd") == 0) { if (++i < argc) { displayfd = atoi(argv[i]); - display = NULL; nolock = TRUE; } else -- cgit v1.2.3 From c468be804ec48231db12f504c2d877ef7a11adc1 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 15 Mar 2017 15:16:37 +0000 Subject: os: Use NotifyFd interface for listen descriptors Bundle X.org backport of these commits: commit 7ea64fb4374504bd3d524fc08c90efdab9f253ea Author: Alan Coopersmith Date: Mon Mar 9 09:55:57 2015 -0700 Clear ListenTransConns entries in CloseWellKnownConnections Since _XSERVTransClose frees the connection pointer passed to it, remove that pointer from the array, so we don't try to double free it if we come back into CloseWellKnownConnections again. Should fix https://bugzilla.yoctoproject.org/show_bug.cgi?id=6665 in which the shutdown section of the main() loop called CloseWellKnownConnections() and then moved on to ddxGiveUp(), which failed to release the VT and thus called AbortServer(), which called CloseWellKnownConnections() again. Signed-off-by: Alan Coopersmith Reviewed-by: Adam Jackson Signed-off-by: Peter Hutterer commit 7b02f0b87ec2fa0cc5a65307a1fd55c671cec884 Author: Keith Packard Date: Wed Nov 11 22:02:17 2015 -0800 os: Use NotifyFd interface for listen descriptors Replace the custom path for dealing with new incoming connections with the general-purpose NotifyFd API. Reviewed-by: Adam Jackson Signed-off-by: Keith Packard commit ba71b69f94f00a6f6910597185610668e79c10be Author: Alan Coopersmith Date: Fri Jan 1 17:34:41 2016 -0800 Avoid segfault in CloseWellKnownConnections when using -displayfd When -displayfd is looping through the possible display ids to use, if it can't open all the listening sockets for one (say when :0 is already in use), it calls CloseWellKnownConnections to close all the ListenTransConns entries before the point that ListenTransFds was allocated & initialized, so CloseWellKnownConnections would segfault trying to read entries from a NULL ListenTransFds pointer. Introduced by commit 7b02f0b8 Signed-off-by: Alan Coopersmith Reviewed-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/os.h | 4 -- nx-X11/programs/Xserver/os/WaitFor.c | 4 -- nx-X11/programs/Xserver/os/connection.c | 119 ++++++++++++++------------------ 3 files changed, 53 insertions(+), 74 deletions(-) diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index 5dd5e2012..1af34a04c 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -137,10 +137,6 @@ extern char *ClientAuthorized( unsigned int /*string_n*/, char* /*auth_string*/); -extern Bool EstablishNewConnections( - ClientPtr /*clientUnused*/, - void * /*closure*/); - extern void CheckConnections(void); extern void CloseDownConnection(ClientPtr /*client*/); diff --git a/nx-X11/programs/Xserver/os/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c index 4d7fe3f84..76e5da5f2 100644 --- a/nx-X11/programs/Xserver/os/WaitFor.c +++ b/nx-X11/programs/Xserver/os/WaitFor.c @@ -495,10 +495,6 @@ WaitForSomething(int *pClientsReady) } XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); - XFD_ANDSET(&tmp_set, &LastSelectMask, &WellKnownConnections); - if (XFD_ANYSET(&tmp_set)) - QueueWorkProc(EstablishNewConnections, NULL, - (void *)&LastSelectMask); XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds); if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady) diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 7638cdfdd..b251c2f5c 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -123,7 +123,6 @@ SOFTWARE. int lastfdesc; /* maximum file descriptor */ -fd_set WellKnownConnections; /* Listener mask */ fd_set NotifyReadFds; /* mask for other file descriptors */ fd_set NotifyWriteFds; /* mask for other write file descriptors */ fd_set AllSockets; /* select on this */ @@ -152,6 +151,9 @@ static fd_set SavedAllSockets; static fd_set SavedClientsWithInput; int GrabInProgress = 0; +static void +QueueNewConnections(int curconn, int ready, void *data); + #if !defined(WIN32) int *ConnectionTranslation = NULL; #else @@ -407,8 +409,6 @@ CreateWellKnownSockets(void) ClearConnectionTranslation(); #endif - FD_ZERO (&WellKnownConnections); - /* display is initialized to "0" by main(). It is then set to the display * number if specified on the command line. */ if (NoListenAll) { @@ -442,13 +442,13 @@ CreateWellKnownSockets(void) int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]); ListenTransFds[i] = fd; - FD_SET(fd, &WellKnownConnections); + SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL); if (!_XSERVTransIsLocal(ListenTransConns[i])) DefineSelf (fd); } - if (!XFD_ANYSET (&WellKnownConnections) && !NoListenAll) + if (ListenTransCount == 0 && !NoListenAll) FatalError ("Cannot establish any listening sockets - Make sure an X server isn't already running"); #if !defined(WIN32) OsSignal (SIGPIPE, SIG_IGN); @@ -456,7 +456,6 @@ CreateWellKnownSockets(void) #endif OsSignal (SIGINT, GiveUp); OsSignal (SIGTERM, GiveUp); - XFD_COPYSET (&WellKnownConnections, &AllSockets); ResetHosts(display); InitParentProcess(); @@ -525,7 +524,7 @@ ResetWellKnownSockets (void) * Remove it from out list. */ - FD_CLR (ListenTransFds[i], &WellKnownConnections); + RemoveNotifyFd(ListenTransFds[i]); ListenTransFds[i] = ListenTransFds[ListenTransCount - 1]; ListenTransConns[i] = ListenTransConns[ListenTransCount - 1]; ListenTransCount -= 1; @@ -539,13 +538,14 @@ ResetWellKnownSockets (void) int newfd = _XSERVTransGetConnectionNumber (ListenTransConns[i]); - FD_CLR (ListenTransFds[i], &WellKnownConnections); ListenTransFds[i] = newfd; - FD_SET(newfd, &WellKnownConnections); } } } + for (i = 0; i < ListenTransCount; i++) + SetNotifyFd(ListenTransFds[i], QueueNewConnections, X_NOTIFY_READ, NULL); + ResetAuthorization (); ResetHosts(display); /* @@ -561,8 +561,15 @@ CloseWellKnownConnections(void) { int i; - for (i = 0; i < ListenTransCount; i++) - _XSERVTransClose (ListenTransConns[i]); + for (i = 0; i < ListenTransCount; i++) { + if (ListenTransConns[i] != NULL) { + _XSERVTransClose(ListenTransConns[i]); + ListenTransConns[i] = NULL; + if (ListenTransFds != NULL) + RemoveNotifyFd(ListenTransFds[i]); + } + } + ListenTransCount = 0; } static void @@ -827,23 +834,18 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) * and AllSockets. *****************/ -/*ARGSUSED*/ -Bool +static Bool EstablishNewConnections(ClientPtr clientUnused, void * 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 */ + int curconn = (int) (intptr_t) closure; + 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; + int i; + ClientPtr client; + OsCommPtr oc; + XtransConnInfo trans_conn, new_trans_conn; + int status; + connect_time = GetTimeInMillis(); /* kill off stragglers */ for (i=1; iflags & TRANS_NOXAUTH) + new_trans_conn->flags = new_trans_conn->flags | TRANS_NOXAUTH; + + if (!AllocNewConnection(new_trans_conn, newconn, connect_time)) { + ErrorConnMax(new_trans_conn); + } - if (!AllocNewConnection (new_trans_conn, newconn, connect_time - )) - { - ErrorConnMax(new_trans_conn); - } - } -#ifndef WIN32 - } -#endif return TRUE; } +static void +QueueNewConnections(int fd, int ready, void *data) +{ + QueueWorkProc(EstablishNewConnections, NULL, (void *) (intptr_t) fd); +} + #define NOROOM "Maximum number of clients reached" /************ -- cgit v1.2.3 From faaba2661306288bb25d9a5a5b81ef80fa6b851f Mon Sep 17 00:00:00 2001 From: Jon TURNEY Date: Wed, 15 Mar 2017 15:40:57 +0000 Subject: os: -displayfd should check ports up to 65535 commit ea5b2b0a2e2143ad1414fcbdc081b5d584588346 Author: Jon TURNEY Date: Tue Oct 21 15:03:55 2014 +0100 os: -displayfd should check ports up to 65535 -displayfd should check ports up to 65535 Noticed during https://cygwin.com/ml/cygwin-xfree/2014-07/msg00024.html Signed-off-by: Jon TURNEY Reviewed-by: Adam Jackson Signed-off-by: Keith Packard Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index b251c2f5c..0d48fda5b 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -422,7 +422,7 @@ CreateWellKnownSockets(void) } else { /* -displayfd and no explicit display number */ Bool found = 0; - for (i = 0; i < 65535 - X_TCP_PORT; i++) { + for (i = 0; i < 65536 - X_TCP_PORT; i++) { if (TryCreateSocket(i, &partial) && !partial) { found = 1; break; -- cgit v1.2.3 From e96e810c2287232000767ee55f2d1b84b31e6291 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 15 Mar 2017 15:42:10 +0000 Subject: Use unique logfile names when starting server with -displayfd commit edcb6426f20c3be5dd5f50b76a686754aef2f64e Author: Alan Coopersmith Date: Fri Jan 1 18:11:14 2016 -0800 Use unique logfile names when starting server with -displayfd Fixes https://bugs.freedesktop.org/show_bug.cgi?id=93212 Previously all X servers started with -displayfd would overwrite Xorg.0.log - now a temporary name of Xorg.pid-.log is used until after -displayfd finds an open display - then it is renamed to the traditional Xorg..log name. Reviewed-by: Adam Jackson Signed-off-by: Alan Coopersmith Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/include/os.h | 1 + nx-X11/programs/Xserver/os/connection.c | 1 + nx-X11/programs/Xserver/os/log.c | 127 ++++++++++++++++++++++++-------- 3 files changed, 100 insertions(+), 29 deletions(-) diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index 1af34a04c..0c7ce6a6f 100644 --- a/nx-X11/programs/Xserver/include/os.h +++ b/nx-X11/programs/Xserver/include/os.h @@ -520,6 +520,7 @@ typedef enum { #endif extern const char *LogInit(const char *fname, const char *backup); +extern void LogSetDisplay(void); extern void LogClose(void); extern Bool LogSetParameter(LogParameter param, int value); extern void LogVWrite(int verb, const char *f, va_list args); diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 0d48fda5b..940b0bd75 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -434,6 +434,7 @@ CreateWellKnownSockets(void) FatalError("Failed to find a socket to listen on"); snprintf(dynamic_display, sizeof(dynamic_display), "%d", i); display = dynamic_display; + LogSetDisplay(); } ListenTransFds = malloc(ListenTransCount * sizeof (int)); diff --git a/nx-X11/programs/Xserver/os/log.c b/nx-X11/programs/Xserver/os/log.c index d82f545a0..0ead6e9f0 100644 --- a/nx-X11/programs/Xserver/os/log.c +++ b/nx-X11/programs/Xserver/os/log.c @@ -178,49 +178,88 @@ static Bool needBuffer = TRUE; #define X_NOT_IMPLEMENTED_STRING "(NI)" #endif +/* + * LogFilePrep is called to setup files for logging, including getting + * an old file out of the way, but it doesn't actually open the file, + * since it may be used for renaming a file we're already logging to. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +static char * +LogFilePrep(const char *fname, const char *backup, const char *idstring) +{ + char *logFileName = NULL; + + if (asprintf(&logFileName, fname, idstring) == -1) + FatalError("Cannot allocate space for the log file name\n"); + + if (backup && *backup) { + struct stat buf; + + if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) { + char *suffix; + char *oldLog; + + if ((asprintf(&suffix, backup, idstring) == -1) || + (asprintf(&oldLog, "%s%s", logFileName, suffix) == -1)) { + FatalError("Cannot allocate space for the log file name\n"); + } + free(suffix); + + if (rename(logFileName, oldLog) == -1) { + FatalError("Cannot move old log file \"%s\" to \"%s\"\n", + logFileName, oldLog); + } + free(oldLog); + } + } + else { + if (remove(logFileName) != 0) { + FatalError("Cannot remove old log file \"%s\": %s\n", + logFileName, strerror(errno)); + } + } + + return logFileName; +} +#pragma GCC diagnostic pop + /* * LogInit is called to start logging to a file. It is also called (with * NULL arguments) when logging to a file is not wanted. It must always be * called, otherwise log messages will continue to accumulate in a buffer. * * %s, if present in the fname or backup strings, is expanded to the display - * string. + * string (or to a string containing the pid if the display is not yet set). */ +static char *saved_log_fname; +static char *saved_log_backup; +static char *saved_log_tempname; + const char * LogInit(const char *fname, const char *backup) { char *logFileName = NULL; if (fname && *fname) { - /* malloc() can't be used yet. */ - logFileName = malloc(strlen(fname) + strlen(display) + 1); - if (!logFileName) - FatalError("Cannot allocate space for the log file name\n"); - sprintf(logFileName, fname, display); - - if (backup && *backup) { - struct stat buf; - - if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) { - char *suffix; - char *oldLog; - - oldLog = malloc(strlen(logFileName) + strlen(backup) + - strlen(display) + 1); - suffix = malloc(strlen(backup) + strlen(display) + 1); - if (!oldLog || !suffix) - FatalError("Cannot allocate space for the log file name\n"); - sprintf(suffix, backup, display); - sprintf(oldLog, "%s%s", logFileName, suffix); - free(suffix); - if (rename(logFileName, oldLog) == -1) { - FatalError("Cannot move old log file (\"%s\" to \"%s\"\n", - logFileName, oldLog); - } - free(oldLog); - } - } + if (displayfd != -1) { + /* Display isn't set yet, so we can't use it in filenames yet. */ + char pidstring[32]; + snprintf(pidstring, sizeof(pidstring), "pid-%ld", + (unsigned long) getpid()); + logFileName = LogFilePrep(fname, backup, pidstring); + saved_log_tempname = logFileName; + + /* Save the patterns for use when the display is named. */ + saved_log_fname = strdup(fname); + if (backup == NULL) + saved_log_backup = NULL; + else + saved_log_backup = strdup(backup); + } else + logFileName = LogFilePrep(fname, backup, display); if ((logFile = fopen(logFileName, "w")) == NULL) FatalError("Cannot open log file \"%s\"\n", logFileName); setvbuf(logFile, NULL, _IONBF, 0); @@ -249,6 +288,36 @@ LogInit(const char *fname, const char *backup) return logFileName; } +void +LogSetDisplay(void) +{ + if (saved_log_fname) { + char *logFileName; + + logFileName = LogFilePrep(saved_log_fname, saved_log_backup, display); + + if (rename(saved_log_tempname, logFileName) == 0) { + LogMessageVerb(X_PROBED, 0, + "Log file renamed from \"%s\" to \"%s\"\n", + saved_log_tempname, logFileName); + + if (strlen(saved_log_tempname) >= strlen(logFileName)) + strncpy(saved_log_tempname, logFileName, + strlen(saved_log_tempname)); + } + else { + ErrorF("Failed to rename log file \"%s\" to \"%s\": %s\n", + saved_log_tempname, logFileName, strerror(errno)); + } + + /* free newly allocated string - can't free old one since existing + pointers to it may exist in DDX callers. */ + free(logFileName); + free(saved_log_fname); + free(saved_log_backup); + } +} + void LogClose() { -- cgit v1.2.3 From a95cfdf48aa5102e16611360917c60b9354192fa Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 15 Mar 2017 15:46:32 +0000 Subject: os: FatalError if -displayfd writes fail AND Clear the -displayfd option after closing the file commit d72f691c0c9cace857975a6608a4cb431c8b6846 Author: Keith Packard Date: Fri Apr 18 15:00:30 2014 -0700 os: FatalError if -displayfd writes fail When the server is started with the -displayfd option, check to make sure that the writes succeed and give up running if they don't. Signed-off-by: Keith Packard Reviewed-by: Jamey Sharp commit 4957e986841225e9984daca76f1a0ee08df125bb Author: Keith Packard Date: Fri Apr 18 15:00:35 2014 -0700 os: Clear the -displayfd option after closing the file Failing to clear this means that we'll attempt to write the display number to a random file descriptor on subsequent X server generations. Signed-off-by: Keith Packard Reviewed-by: Jamey Sharp Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/os/connection.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 940b0bd75..8a5eb756a 100644 --- a/nx-X11/programs/Xserver/os/connection.c +++ b/nx-X11/programs/Xserver/os/connection.c @@ -364,8 +364,12 @@ NotifyParentProcess(void) { #if !defined(WIN32) if (displayfd >= 0) { - write(displayfd, display, strlen(display)); - close(displayfd); + if (write(displayfd, display, strlen(display)) != strlen(display)) + FatalError("Cannot write display number to fd %d\n", displayfd); + if (write(displayfd, "\n", 1) != 1) + FatalError("Cannot write display number to fd %d\n", displayfd); + close(displayfd); + displayfd = -1; } if (RunFromSmartParent) { if (ParentProcess > 1) { -- cgit v1.2.3 From 565421ba18a09d20620e01fc877915a8b09a3735 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 20 Mar 2017 13:22:50 +0100 Subject: os: Remove the useless -x option commit cbb165ab88cb0810268001e84d87671440baf837 Author: Adam Jackson Date: Fri Apr 3 18:34:45 2009 -0400 os: Remove the useless -x option Backported-to-NX-by: Mike Gabriel --- nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 | 4 ---- nx-X11/programs/Xserver/os/utils.c | 9 --------- 2 files changed, 13 deletions(-) diff --git a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index 66f25b438..d204acdc5 100644 --- a/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 +++ b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 @@ -302,10 +302,6 @@ required by the X protocol, which allows the server to exceed the client's backing store expectations but does not provide a way to tell the client that it is doing so. .TP 8 -.B \-x \fIextension\fP -loads the specified extension at init. -This is a no-op for most implementations. -.TP 8 .B [+-]xinerama enables(+) or disables(-) XINERAMA provided via the PanoramiX extension. This is set to off by default. diff --git a/nx-X11/programs/Xserver/os/utils.c b/nx-X11/programs/Xserver/os/utils.c index 6995d05d5..31ea55bc3 100644 --- a/nx-X11/programs/Xserver/os/utils.c +++ b/nx-X11/programs/Xserver/os/utils.c @@ -622,7 +622,6 @@ void UseMsg(void) ErrorF("v video blanking for screen-saver\n"); ErrorF("-v screen-saver without video blanking\n"); ErrorF("-wm WhenMapped default backing-store\n"); - ErrorF("-x string loads named extension at init time \n"); ErrorF("-maxbigreqsize set maximal bigrequest size \n"); #ifdef PANORAMIX ErrorF("+xinerama Enable XINERAMA (PanoramiX) extension\n"); @@ -1012,14 +1011,6 @@ ProcessCommandLine(int argc, char *argv[]) noRRXineramaExtension = TRUE; } #endif - else if ( strcmp( argv[i], "-x") == 0) - { - if(++i >= argc) - UseMsg(); - /* For U**x, which doesn't support dynamic loading, there's nothing - * to do when we see a -x. Either the extension is linked in or - * it isn't */ - } else if ( strcmp( argv[i], "-I") == 0) { /* ignore all remaining arguments */ -- cgit v1.2.3