diff options
author | Mihai Moldovan <ionic@ionic.de> | 2017-03-22 00:40:55 +0100 |
---|---|---|
committer | Mihai Moldovan <ionic@ionic.de> | 2017-03-22 00:40:55 +0100 |
commit | f5e7d555ad58368cb550b4516b75a1ac3765fda2 (patch) | |
tree | 000ba384ea14d1c4ba4b8023b37ec57f95c88f58 | |
parent | b7c389b9a0fa366a40ab272a9429a52ecee7365d (diff) | |
parent | 565421ba18a09d20620e01fc877915a8b09a3735 (diff) | |
download | nx-libs-f5e7d555ad58368cb550b4516b75a1ac3765fda2.tar.gz nx-libs-f5e7d555ad58368cb550b4516b75a1ac3765fda2.tar.bz2 nx-libs-f5e7d555ad58368cb550b4516b75a1ac3765fda2.zip |
Merge branch 'sunweaver-pr/various-os-backports' into 3.6.x
Attributes GH PR #376: https://github.com/ArcticaProject/nx-libs/pull/376
28 files changed, 1340 insertions, 554 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/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/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 <sys/signal.h> 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..4c8f02c2c 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 <sys/signal.h> - 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); } @@ -368,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 @@ -432,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/dix/dispatch.c b/nx-X11/programs/Xserver/dix/dispatch.c index 7b2aa7b3d..438436526 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)) @@ -221,7 +222,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; @@ -240,15 +245,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 +267,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 +293,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 +322,7 @@ SmartScheduleClient (int *clientReady, int nready) { SmartScheduleSlice = SmartScheduleInterval; } - return best; + return best->index; } #ifndef NXAGENT_SERVER @@ -348,7 +356,7 @@ Dispatch(void) nready = WaitForSomething(clientReady); - if (nready && !SmartScheduleDisable) + if (nready) { clientReady[0] = SmartScheduleClient (clientReady, nready); nready = 1; @@ -383,8 +391,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) @@ -412,7 +419,10 @@ Dispatch(void) result = BadLength; else result = (* client->requestVector[MAJOROP])(client); - + + if (!SmartScheduleSignalEnable) + SmartScheduleTime = GetTimeInMillis(); + if (result != Success) { if (client->noClientException != Success) @@ -3551,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; @@ -3634,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; @@ -3715,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; @@ -3733,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); @@ -3750,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/dix/globals.c b/nx-X11/programs/Xserver/dix/globals.c index a0af50fa8..f9fa544ed 100644 --- a/nx-X11/programs/Xserver/dix/globals.c +++ b/nx-X11/programs/Xserver/dix/globals.c @@ -149,6 +149,8 @@ int defaultColorVisualClass = -1; int monitorResolution = 0; char *display; +int displayfd = -1; +Bool explicit_display = FALSE; CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; int argcGlobal; diff --git a/nx-X11/programs/Xserver/dix/main.c b/nx-X11/programs/Xserver/dix/main.c index 7bd41d865..72ed40108 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) { @@ -430,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 */ @@ -470,6 +474,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/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/hw/nxagent/man/nxagent.1 b/nx-X11/programs/Xserver/hw/nxagent/man/nxagent.1 index af5fc88f8..d204acdc5 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), @@ -295,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/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 <rami.ylimaki@vincit.fi> */ + +#ifndef CLIENT_H +#define CLIENT_H + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif /* HAVE_DIX_CONFIG_H */ +#include <X11/Xfuncproto.h> +#include <sys/types.h> + +/* 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 3c97e5bb7..cdd2543a6 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" @@ -94,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; @@ -141,6 +143,8 @@ typedef struct _Client { long smart_start_tick; long smart_stop_tick; long smart_check_tick; + + ClientIdPtr clientIds; } ClientRec; /* @@ -150,18 +154,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/include/opaque.h b/nx-X11/programs/Xserver/include/opaque.h index bd286ba12..8312b4a21 100644 --- a/nx-X11/programs/Xserver/include/opaque.h +++ b/nx-X11/programs/Xserver/include/opaque.h @@ -52,6 +52,8 @@ extern int defaultScreenSaverAllowExposures; extern int argcGlobal; extern char **argvGlobal; extern char *display; +extern int displayfd; +extern Bool explicit_display; extern int defaultBackingStore; extern Bool disableBackingStore; @@ -76,6 +78,6 @@ extern long maxBigRequestSize; extern Bool blackRoot; extern Bool CoreDump; - +extern Bool NoListenAll; #endif /* OPAQUE_H */ diff --git a/nx-X11/programs/Xserver/include/os.h b/nx-X11/programs/Xserver/include/os.h index 99003922f..0c7ce6a6f 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); @@ -135,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*/); @@ -317,10 +315,26 @@ 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) +#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); @@ -506,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/Imakefile b/nx-X11/programs/Xserver/os/Imakefile index 8b260fa32..7932e32cd 100644 --- a/nx-X11/programs/Xserver/os/Imakefile +++ b/nx-X11/programs/Xserver/os/Imakefile @@ -25,25 +25,31 @@ #include <Server.tmpl> +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 -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 \ + -DNXAGENT_SERVER \ + $(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 +127,53 @@ 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 \ + client.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 \ + client.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 +186,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 @@ -176,7 +240,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/WaitFor.c b/nx-X11/programs/Xserver/os/WaitFor.c index 3ac2e1c7e..76e5da5f2 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) @@ -507,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) @@ -544,17 +528,14 @@ WaitForSomething(int *pClientsReady) #ifndef WIN32 for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++) { - int highest_priority = 0; - while (clientsReadable.fds_bits[i]) { - int client_priority, client_index; + int client_index; curclient = ffs (clientsReadable.fds_bits[i]) - 1; client_index = /* raphael: modified */ ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))]; #else - int highest_priority = 0; fd_set savedClientsReadable; XFD_COPYSET(&clientsReadable, &savedClientsReadable); for (i = 0; i < XFD_SETCOUNT(&savedClientsReadable); i++) @@ -564,40 +545,10 @@ WaitForSomething(int *pClientsReady) curclient = XFD_FD(&savedClientsReadable, i); client_index = GetConnectionTranslation(curclient); #endif -#ifdef XSYNC - /* We implement "strict" priorities. - * Only the highest priority client is returned to - * dix. If multiple clients at the same priority are - * ready, they are all returned. This means that an - * aggressive client could take over the server. - * This was not considered a big problem because - * aggressive clients can hose the server in so many - * other ways :) - */ - client_priority = clients[client_index]->priority; - 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 diff --git a/nx-X11/programs/Xserver/os/access.c b/nx-X11/programs/Xserver/os/access.c index d3a18efbe..d8d035ade 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<display>.hosts, we've added a requested field to the HOST struct, and a LocalHostRequested variable. These default to FALSE, but are set @@ -496,7 +492,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 +627,7 @@ DefineLocalHost: selfhosts = host; } } -#endif /* !TCPCONN && !UNIXCONN && !MNX_TCPCONN */ +#endif /* !TCPCONN && !UNIXCONN */ } #else @@ -893,6 +889,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) @@ -1068,11 +1066,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; @@ -1117,7 +1114,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; @@ -1162,7 +1159,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) || @@ -1220,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 */ @@ -1236,65 +1238,79 @@ 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); 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; } /* * 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); @@ -1313,57 +1329,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 @@ -1373,12 +1396,23 @@ 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) { 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 @@ -1593,7 +1627,7 @@ CheckAddr ( switch (family) { -#if defined(TCPCONN) || defined(MNX_TCPCONN) +#if defined(TCPCONN) case FamilyInternet: if (length == sizeof (struct in_addr)) len = length; @@ -1686,7 +1720,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) @@ -2176,38 +2210,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/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 <rami.ylimaki@vincit.fi> + */ + +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> + +#include "client.h" +#include "os.h" +#include "dixstruct.h" + +#ifdef __sun +#include <errno.h> +#include <procfs.h> +#endif + +#ifdef __OpenBSD__ +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/types.h> + +#include <kvm.h> +#include <limits.h> +#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; +} diff --git a/nx-X11/programs/Xserver/os/connection.c b/nx-X11/programs/Xserver/os/connection.c index 966fe208d..8a5eb756a 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 <nx-X11/Xtrans/Xtrans.h> +#include <nx-X11/Xtrans/Xtransint.h> #include <errno.h> #include <signal.h> #include <stdio.h> @@ -122,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 */ @@ -136,7 +136,9 @@ 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 */ static Pid_t ParentProcess; @@ -149,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 @@ -319,6 +324,72 @@ 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 (displayfd >= 0) { + 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) { + kill (ParentProcess, SIGUSR1); + } + } +#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 @@ -330,8 +401,6 @@ CreateWellKnownSockets(void) { int i; int partial; - char port[20]; - OsSigHandlerPtr handler; FD_ZERO(&AllSockets); FD_ZERO(&AllClients); @@ -344,38 +413,47 @@ 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) { + ListenTransCount = 0; + } + 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 and no explicit display number */ + Bool found = 0; + for (i = 0; i < 65536 - 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; + LogSetDisplay(); + } - sprintf (port, "%d", atoi (display)); + ListenTransFds = malloc(ListenTransCount * sizeof (int)); - 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]); - for (i = 0; i < ListenTransCount; i++) - { - int fd = _XSERVTransGetConnectionNumber (ListenTransConns[i]); - - ListenTransFds[i] = fd; - FD_SET (fd, &WellKnownConnections); - - if (!_XSERVTransIsLocal (ListenTransConns[i])) - { - DefineSelf (fd); - } - } - } + ListenTransFds[i] = fd; + SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL); + + if (!_XSERVTransIsLocal(ListenTransConns[i])) + DefineSelf (fd); } - if (!XFD_ANYSET (&WellKnownConnections)) + 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); @@ -383,35 +461,10 @@ CreateWellKnownSockets(void) #endif OsSignal (SIGINT, GiveUp); 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 @@ -476,7 +529,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; @@ -490,26 +543,17 @@ 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); /* - * See above in CreateWellKnownSockets about SIGUSR1 - */ -#if !defined(WIN32) - if (RunFromSmartParent) { - if (ParentProcess > 1) { - kill (ParentProcess, SIGUSR1); - } - } -#endif - /* * restart XDMCP */ #ifdef XDMCP @@ -522,8 +566,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 @@ -534,10 +585,9 @@ 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); - } + char client_uid_string[64]; + LocalClientCredRec *lcc; + if (!len) strcpy(out, "local host"); else @@ -549,7 +599,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)); @@ -567,14 +617,56 @@ AuthAudit (ClientPtr client, Bool letin, default: strcpy(out, "unknown address"); } - + + 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'; + } + 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 @@ -713,6 +805,7 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) free (oc); return NullClient; } + client->local = ComputeLocalClient(client); { #if !defined(WIN32) ConnectionTranslation[fd] = client->index; @@ -746,23 +839,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; i<currentMaxClients; i++) @@ -776,60 +864,44 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure) CloseDownClient(client); } } -#ifndef WIN32 - for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) - { - while (readyconnections.fds_bits[i]) -#else - for (i = 0; i < XFD_SETCOUNT(&readyconnections); i++) -#endif - { - XtransConnInfo trans_conn, new_trans_conn; - int status; - -#ifndef WIN32 - curconn = ffs (readyconnections.fds_bits[i]) - 1; - readyconnections.fds_bits[i] &= ~((fd_mask)1 << curconn); - curconn += (i * (sizeof(fd_mask)*8)); -#else - curconn = XFD_FD(&readyconnections, i); -#endif + if ((trans_conn = lookup_trans_conn(curconn)) == NULL) + return TRUE; - if ((trans_conn = lookup_trans_conn (curconn)) == NULL) - continue; + if ((new_trans_conn = _XSERVTransAccept(trans_conn, &status)) == NULL) + return TRUE; - if ((new_trans_conn = _XSERVTransAccept (trans_conn, &status)) == NULL) - continue; + newconn = _XSERVTransGetConnectionNumber(new_trans_conn); - newconn = _XSERVTransGetConnectionNumber (new_trans_conn); + if (newconn < lastfdesc) { + int clientid; - if (newconn < lastfdesc) - { - int clientid; #if !defined(WIN32) - clientid = ConnectionTranslation[newconn]; + clientid = ConnectionTranslation[newconn]; #else - clientid = GetConnectionTranslation(newconn); + clientid = GetConnectionTranslation(newconn); #endif - if(clientid && (client = clients[clientid])) - CloseDownClient(client); - } + if (clientid && (client = clients[clientid])) + CloseDownClient(client); + } - _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); + _XSERVTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1); + + if (trans_conn->flags & 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); - _XSERVTransClose(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" /************ @@ -838,35 +910,28 @@ 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]; - char byteOrder = 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); + XtransConnInfo trans_conn = data; + char order = 0; + /* 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') { + + 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; 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); @@ -880,6 +945,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); } /************ @@ -987,6 +1061,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 92a3f0476..07399438e 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; /* @@ -430,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) { @@ -755,9 +781,6 @@ FlushAllOutput(void) fd_set newOutputPending; #endif - if (FlushCallback) - CallCallbacks(&FlushCallback, NULL); - if (!newoutput) return; @@ -958,7 +981,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)) { @@ -971,7 +994,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); } @@ -1004,6 +1031,13 @@ 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; + + if (FlushCallback) + CallCallbacks(&FlushCallback, who); + todo = notWritten; while (notWritten) { long before = written; /* amount of whole thing written */ @@ -1083,10 +1117,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); @@ -1173,6 +1208,7 @@ AllocateInputBuffer(void) oci->bufptr = oci->buffer; oci->bufcnt = 0; oci->lenLastReq = 0; + oci->ignoreBytes = 0; return oci; } @@ -1217,6 +1253,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/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 @@ -179,48 +179,87 @@ static Bool needBuffer = TRUE; #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); @@ -250,6 +289,36 @@ LogInit(const char *fname, const char *backup) } 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() { if (logFile) { diff --git a/nx-X11/programs/Xserver/os/osdep.h b/nx-X11/programs/Xserver/os/osdep.h index 6ac9d860e..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 @@ -129,6 +128,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 { @@ -238,6 +238,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); 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..31ea55bc3 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 } @@ -337,7 +338,7 @@ LockServer(void) int len; char port[20]; - if (nolock) return; + if (nolock || NoListenAll) return; /* * Path names */ @@ -463,7 +464,7 @@ LockServer(void) void UnlockServer(void) { - if (nolock) return; + if (nolock || NoListenAll) return; if (!StillLocking){ @@ -621,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"); @@ -703,6 +703,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); @@ -779,6 +780,15 @@ ProcessCommandLine(int argc, char *argv[]) else UseMsg(); } + else if (strcmp(argv[i], "-displayfd") == 0) { + if (++i < argc) { + displayfd = atoi(argv[i]); + nolock = TRUE; + } + else + UseMsg(); + } + #ifdef DPMSExtension else if ( strcmp( argv[i], "dpms") == 0) DPMSEnabledSwitch = TRUE; @@ -891,6 +901,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]); @@ -996,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 */ @@ -1026,10 +1033,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 +1362,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 +1380,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 +1557,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 +1599,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 +1635,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 +1657,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 +1735,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); } 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, |