aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Moldovan <ionic@ionic.de>2017-03-22 00:40:55 +0100
committerMihai Moldovan <ionic@ionic.de>2017-03-22 00:40:55 +0100
commitf5e7d555ad58368cb550b4516b75a1ac3765fda2 (patch)
tree000ba384ea14d1c4ba4b8023b37ec57f95c88f58
parentb7c389b9a0fa366a40ab272a9429a52ecee7365d (diff)
parent565421ba18a09d20620e01fc877915a8b09a3735 (diff)
downloadnx-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
-rw-r--r--nx-X11/config/cf/Imake.tmpl9
-rw-r--r--nx-X11/programs/Xserver/Imakefile9
-rw-r--r--nx-X11/programs/Xserver/Xext/shm.c5
-rw-r--r--nx-X11/programs/Xserver/Xext/xf86bigfont.c10
-rw-r--r--nx-X11/programs/Xserver/dix/dispatch.c63
-rw-r--r--nx-X11/programs/Xserver/dix/globals.c2
-rw-r--r--nx-X11/programs/Xserver/dix/main.c5
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Display.c2
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Display.h29
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/Handlers.c8
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXdispatch.c9
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/man/nxagent.111
-rw-r--r--nx-X11/programs/Xserver/include/Imakefile1
-rw-r--r--nx-X11/programs/Xserver/include/client.h60
-rw-r--r--nx-X11/programs/Xserver/include/dixstruct.h21
-rw-r--r--nx-X11/programs/Xserver/include/opaque.h4
-rw-r--r--nx-X11/programs/Xserver/include/os.h27
-rw-r--r--nx-X11/programs/Xserver/os/Imakefile130
-rw-r--r--nx-X11/programs/Xserver/os/WaitFor.c73
-rw-r--r--nx-X11/programs/Xserver/os/access.c202
-rw-r--r--nx-X11/programs/Xserver/os/client.c397
-rw-r--r--nx-X11/programs/Xserver/os/connection.c397
-rw-r--r--nx-X11/programs/Xserver/os/io.c81
-rw-r--r--nx-X11/programs/Xserver/os/log.c127
-rw-r--r--nx-X11/programs/Xserver/os/osdep.h5
-rw-r--r--nx-X11/programs/Xserver/os/osinit.c5
-rw-r--r--nx-X11/programs/Xserver/os/utils.c192
-rw-r--r--nx-X11/programs/Xserver/os/xdmcp.c10
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,
- &notused, &alen, &from))
+ if (!_XSERVTransGetPeerAddr (oc->trans_conn, &notused, &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,