Unverified Commit f5e7d555 authored by Mihai Moldovan's avatar Mihai Moldovan

Merge branch 'sunweaver-pr/various-os-backports' into 3.6.x

parents b7c389b9 565421ba
...@@ -1289,6 +1289,12 @@ TCLIBDIR = TclLibDir ...@@ -1289,6 +1289,12 @@ TCLIBDIR = TclLibDir
#ifndef ToolkitStringsABIOptions #ifndef ToolkitStringsABIOptions
#define ToolkitStringsABIOptions /**/ #define ToolkitStringsABIOptions /**/
#endif #endif
#ifndef HasSetitimer
#define HasSetitimer YES
#endif
#ifndef HasSetitimerDefines
#define HasSetitimerDefines -DHAVE_SETITIMER=1
#endif
#ifndef HasLdRunPath #ifndef HasLdRunPath
#define HasLdRunPath NO #define HasLdRunPath NO
#endif #endif
...@@ -1841,6 +1847,7 @@ MODLDCOMBINEFLAGS = ModuleLdCombineFlags ...@@ -1841,6 +1847,7 @@ MODLDCOMBINEFLAGS = ModuleLdCombineFlags
STD_CPP_OPTIONS = StandardCppOptions STD_CPP_OPTIONS = StandardCppOptions
STD_CPP_DEFINES = StandardCppOptions StandardCppDefines $(PROJECT_DEFINES) STD_CPP_DEFINES = StandardCppOptions StandardCppDefines $(PROJECT_DEFINES)
STD_DEFINES = StandardDefines $(PROJECT_DEFINES) STD_DEFINES = StandardDefines $(PROJECT_DEFINES)
SETITIMER_DEFINES = HasSetitimerDefines
EXTRA_LOAD_FLAGS = ExtraLoadFlags EXTRA_LOAD_FLAGS = ExtraLoadFlags
EXTRA_LDOPTIONS = ExtraLoadOptions EXTRA_LDOPTIONS = ExtraLoadOptions
EXTRA_LIBRARIES = MallocLibraries ExtraLibraries EXTRA_LIBRARIES = MallocLibraries ExtraLibraries
...@@ -1966,7 +1973,7 @@ MODLDCOMBINEFLAGS = ModuleLdCombineFlags ...@@ -1966,7 +1973,7 @@ MODLDCOMBINEFLAGS = ModuleLdCombineFlags
* LOCAL_LDFLAGS contains client-specific ld flags flags set in Imakefile * LOCAL_LDFLAGS contains client-specific ld flags flags set in Imakefile
*/ */
ALLINCLUDES = $(INCLUDES) $(EXTRA_INCLUDES) $(TOP_INCLUDES) $(INSTALLED_INCLUDES) $(STD_INCLUDES) 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) CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(THREADS_CFLAGS) $(MODULE_CFLAGS) $(ALLDEFINES)
LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) $(DEPEND_DEFINES) LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES) $(DEPEND_DEFINES)
LDPRELIB = LdPreLib $(INSTALLED_LIBS) LDPRELIB = LdPreLib $(INSTALLED_LIBS)
......
...@@ -323,6 +323,15 @@ NXAGENTNXLIBS = -L../../../nxcomp \ ...@@ -323,6 +323,15 @@ NXAGENTNXLIBS = -L../../../nxcomp \
-lXcompshad \ -lXcompshad \
-lXrender -lXfixes -lXfont -lXcomposite -lXdmcp \ -lXrender -lXfixes -lXfont -lXcomposite -lXdmcp \
-lNX_X11 -lXext -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 #else
NXAGENTNXLIBS = -L../../../nxcomp \ NXAGENTNXLIBS = -L../../../nxcomp \
-L../../../nx-X11/exports/lib \ -L../../../nx-X11/exports/lib \
......
...@@ -150,7 +150,6 @@ static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage}; ...@@ -150,7 +150,6 @@ static ShmFuncs fbFuncs = {fbShmCreatePixmap, fbShmPutImage};
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
#include <sys/signal.h>
static Bool badSysCall = FALSE; static Bool badSysCall = FALSE;
...@@ -167,7 +166,7 @@ static Bool CheckForShmSyscall() ...@@ -167,7 +166,7 @@ static Bool CheckForShmSyscall()
int shmid = -1; int shmid = -1;
/* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
oldHandler = signal(SIGSYS, SigSysHandler); oldHandler = OsSignal(SIGSYS, SigSysHandler);
badSysCall = FALSE; badSysCall = FALSE;
shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
...@@ -182,7 +181,7 @@ static Bool CheckForShmSyscall() ...@@ -182,7 +181,7 @@ static Bool CheckForShmSyscall()
/* Allocation failed */ /* Allocation failed */
badSysCall = TRUE; badSysCall = TRUE;
} }
signal(SIGSYS, oldHandler); OsSignal(SIGSYS, oldHandler);
return(!badSysCall); return(!badSysCall);
} }
......
...@@ -106,8 +106,6 @@ static Bool badSysCall = FALSE; ...@@ -106,8 +106,6 @@ static Bool badSysCall = FALSE;
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
#include <sys/signal.h>
static void static void
SigSysHandler( SigSysHandler(
int signo) int signo)
...@@ -122,7 +120,7 @@ CheckForShmSyscall(void) ...@@ -122,7 +120,7 @@ CheckForShmSyscall(void)
int shmid = -1; int shmid = -1;
/* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
oldHandler = signal(SIGSYS, SigSysHandler); oldHandler = OsSignal(SIGSYS, SigSysHandler);
badSysCall = FALSE; badSysCall = FALSE;
shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
...@@ -136,7 +134,7 @@ CheckForShmSyscall(void) ...@@ -136,7 +134,7 @@ CheckForShmSyscall(void)
/* Allocation failed */ /* Allocation failed */
badSysCall = TRUE; badSysCall = TRUE;
} }
signal(SIGSYS, oldHandler); OsSignal(SIGSYS, oldHandler);
return (!badSysCall); return (!badSysCall);
} }
...@@ -368,7 +366,7 @@ ProcXF86BigfontQueryVersion( ...@@ -368,7 +366,7 @@ ProcXF86BigfontQueryVersion(
#endif #endif
reply.capabilities = reply.capabilities =
#ifdef HAS_SHM #ifdef HAS_SHM
(LocalClient(client) && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0) (client->local && !client->swapped ? XF86Bigfont_CAP_LocalShm : 0)
#else #else
0 0
#endif #endif
...@@ -432,7 +430,7 @@ ProcXF86BigfontQueryFont( ...@@ -432,7 +430,7 @@ ProcXF86BigfontQueryFont(
#else #else
switch (client->req_len) { switch (client->req_len) {
case 2: /* client with version 1.0 libX11 */ 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; break;
case 3: /* client with version 1.1 libX11 */ case 3: /* client with version 1.1 libX11 */
stuff_flags = stuff->flags; stuff_flags = stuff->flags;
......
...@@ -112,6 +112,7 @@ int ProcInitialConnection(); ...@@ -112,6 +112,7 @@ int ProcInitialConnection();
#include "inputstr.h" #include "inputstr.h"
#include "xkbsrv.h" #include "xkbsrv.h"
#endif #endif
#include "client.h"
#define mskcnt ((MAXCLIENTS + 31) / 32) #define mskcnt ((MAXCLIENTS + 31) / 32)
#define BITMASK(i) (1U << ((i) & 31)) #define BITMASK(i) (1U << ((i) & 31))
...@@ -221,7 +222,11 @@ InitSelections() ...@@ -221,7 +222,11 @@ InitSelections()
#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ #define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
#define SMART_SCHEDULE_MAX_SLICE 200 /* 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 SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
...@@ -240,15 +245,13 @@ void InitProcVectors(void); ...@@ -240,15 +245,13 @@ void InitProcVectors(void);
int int
SmartScheduleClient (int *clientReady, int nready) SmartScheduleClient (int *clientReady, int nready)
{ {
ClientPtr pClient;
int i; int i;
int client; int client;
int bestPrio, best = 0; ClientPtr pClient, best = NULL;
int bestRobin, robin; int bestRobin, robin;
long now = SmartScheduleTime; long now = SmartScheduleTime;
long idle; long idle;
bestPrio = -0x7fffffff;
bestRobin = 0; bestRobin = 0;
idle = 2 * SmartScheduleSlice; idle = 2 * SmartScheduleSlice;
for (i = 0; i < nready; i++) for (i = 0; i < nready; i++)
...@@ -264,13 +267,19 @@ SmartScheduleClient (int *clientReady, int nready) ...@@ -264,13 +267,19 @@ SmartScheduleClient (int *clientReady, int nready)
pClient->smart_check_tick = now; pClient->smart_check_tick = now;
/* check priority to select best client */ /* check priority to select best client */
robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff; robin = (pClient->index -
if (pClient->smart_priority > bestPrio || SmartLastIndex[pClient->smart_priority -
(pClient->smart_priority == bestPrio && robin > bestRobin)) 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; bestRobin = robin;
best = client;
} }
#ifdef SMART_DEBUG #ifdef SMART_DEBUG
if ((now - SmartLastPrint) >= 5000) if ((now - SmartLastPrint) >= 5000)
...@@ -284,8 +293,7 @@ SmartScheduleClient (int *clientReady, int nready) ...@@ -284,8 +293,7 @@ SmartScheduleClient (int *clientReady, int nready)
SmartLastPrint = now; SmartLastPrint = now;
} }
#endif #endif
pClient = clients[best]; SmartLastIndex[best->smart_priority - SMART_MIN_PRIORITY] = best->index;
SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
/* /*
* Set current client pointer * Set current client pointer
*/ */
...@@ -314,7 +322,7 @@ SmartScheduleClient (int *clientReady, int nready) ...@@ -314,7 +322,7 @@ SmartScheduleClient (int *clientReady, int nready)
{ {
SmartScheduleSlice = SmartScheduleInterval; SmartScheduleSlice = SmartScheduleInterval;
} }
return best; return best->index;
} }
#ifndef NXAGENT_SERVER #ifndef NXAGENT_SERVER
...@@ -348,7 +356,7 @@ Dispatch(void) ...@@ -348,7 +356,7 @@ Dispatch(void)
nready = WaitForSomething(clientReady); nready = WaitForSomething(clientReady);
if (nready && !SmartScheduleDisable) if (nready)
{ {
clientReady[0] = SmartScheduleClient (clientReady, nready); clientReady[0] = SmartScheduleClient (clientReady, nready);
nready = 1; nready = 1;
...@@ -383,8 +391,7 @@ Dispatch(void) ...@@ -383,8 +391,7 @@ Dispatch(void)
ProcessInputEvents(); ProcessInputEvents();
FlushIfCriticalOutputPending(); FlushIfCriticalOutputPending();
} }
if (!SmartScheduleDisable && if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice)
(SmartScheduleTime - start_tick) >= SmartScheduleSlice)
{ {
/* Penalize clients which consume ticks */ /* Penalize clients which consume ticks */
if (client->smart_priority > SMART_MIN_PRIORITY) if (client->smart_priority > SMART_MIN_PRIORITY)
...@@ -412,7 +419,10 @@ Dispatch(void) ...@@ -412,7 +419,10 @@ Dispatch(void)
result = BadLength; result = BadLength;
else else
result = (* client->requestVector[MAJOROP])(client); result = (* client->requestVector[MAJOROP])(client);
if (!SmartScheduleSignalEnable)
SmartScheduleTime = GetTimeInMillis();
if (result != Success) if (result != Success)
{ {
if (client->noClientException != Success) if (client->noClientException != Success)
...@@ -3551,6 +3561,9 @@ CloseDownClient(register ClientPtr client) ...@@ -3551,6 +3561,9 @@ CloseDownClient(register ClientPtr client)
CallCallbacks((&ClientStateCallback), (void *)&clientinfo); CallCallbacks((&ClientStateCallback), (void *)&clientinfo);
} }
FreeClientResources(client); FreeClientResources(client);
/* Disable client ID tracking. This must be done after
* ClientStateCallback. */
ReleaseClientIds(client);
if (client->index < nextFreeClientID) if (client->index < nextFreeClientID)
nextFreeClientID = client->index; nextFreeClientID = client->index;
clients[client->index] = NullClient; clients[client->index] = NullClient;
...@@ -3634,6 +3647,7 @@ void InitClient(ClientPtr client, int i, void * ospriv) ...@@ -3634,6 +3647,7 @@ void InitClient(ClientPtr client, int i, void * ospriv)
client->smart_start_tick = SmartScheduleTime; client->smart_start_tick = SmartScheduleTime;
client->smart_stop_tick = SmartScheduleTime; client->smart_stop_tick = SmartScheduleTime;
client->smart_check_tick = SmartScheduleTime; client->smart_check_tick = SmartScheduleTime;
client->clientIds = NULL;
} }
extern int clientPrivateLen; extern int clientPrivateLen;
...@@ -3715,6 +3729,11 @@ ClientPtr NextAvailableClient(void * ospriv) ...@@ -3715,6 +3729,11 @@ ClientPtr NextAvailableClient(void * ospriv)
currentMaxClients++; currentMaxClients++;
while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
nextFreeClientID++; nextFreeClientID++;
/* Enable client ID tracking. This must be done before
* ClientStateCallback. */
ReserveClientIds(client);
if (ClientStateCallback) if (ClientStateCallback)
{ {
NewClientInfoRec clientinfo; NewClientInfoRec clientinfo;
...@@ -3733,12 +3752,14 @@ ProcInitialConnection(register ClientPtr client) ...@@ -3733,12 +3752,14 @@ ProcInitialConnection(register ClientPtr client)
REQUEST(xReq); REQUEST(xReq);
register xConnClientPrefix *prefix; register xConnClientPrefix *prefix;
int whichbyte = 1; int whichbyte = 1;
char order;
prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 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); return (client->noClientException = -1);
if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
(!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) (!(*(char *) &whichbyte) && (order == 'l' || order == 'r')))
{ {
client->swapped = TRUE; client->swapped = TRUE;
SwapConnClientPrefix(prefix); SwapConnClientPrefix(prefix);
...@@ -3750,6 +3771,10 @@ ProcInitialConnection(register ClientPtr client) ...@@ -3750,6 +3771,10 @@ ProcInitialConnection(register ClientPtr client)
{ {
swaps(&stuff->length); swaps(&stuff->length);
} }
if (order == 'r' || order == 'R')
{
client->local = FALSE;
}
ResetCurrentRequest(client); ResetCurrentRequest(client);
return (client->noClientException); return (client->noClientException);
} }
......
...@@ -149,6 +149,8 @@ int defaultColorVisualClass = -1; ...@@ -149,6 +149,8 @@ int defaultColorVisualClass = -1;
int monitorResolution = 0; int monitorResolution = 0;
char *display; char *display;
int displayfd = -1;
Bool explicit_display = FALSE;
CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND; CARD32 TimeOutValue = DEFAULT_TIMEOUT * MILLI_PER_SECOND;
int argcGlobal; int argcGlobal;
......
...@@ -100,6 +100,7 @@ Equipment Corporation. ...@@ -100,6 +100,7 @@ Equipment Corporation.
#include "site.h" #include "site.h"
#include "dixfont.h" #include "dixfont.h"
#include "extnsionst.h" #include "extnsionst.h"
#include "client.h"
#ifdef PANORAMIX #ifdef PANORAMIX
#include "panoramiXsrv.h" #include "panoramiXsrv.h"
#else #else
...@@ -382,6 +383,7 @@ main(int argc, char *argv[], char *envp[]) ...@@ -382,6 +383,7 @@ main(int argc, char *argv[], char *envp[])
InitInput(argc, argv); InitInput(argc, argv);
if (InitAndStartDevices() != Success) if (InitAndStartDevices() != Success)
FatalError("failed to initialize core devices"); FatalError("failed to initialize core devices");
ReserveClientIds(serverClient);
InitFonts(); InitFonts();
if (loadableFonts) { if (loadableFonts) {
...@@ -430,6 +432,8 @@ main(int argc, char *argv[], char *envp[]) ...@@ -430,6 +432,8 @@ main(int argc, char *argv[], char *envp[])
FatalError("could not create connection block info"); FatalError("could not create connection block info");
} }
NotifyParentProcess();
Dispatch(); Dispatch();
/* Now free up whatever must be freed */ /* Now free up whatever must be freed */
...@@ -470,6 +474,7 @@ main(int argc, char *argv[], char *envp[]) ...@@ -470,6 +474,7 @@ main(int argc, char *argv[], char *envp[])
#endif #endif
FreeAuditTimer(); FreeAuditTimer();
ReleaseClientIds(serverClient);
free(serverClient->devPrivates); free(serverClient->devPrivates);
serverClient->devPrivates = NULL; serverClient->devPrivates = NULL;
......
...@@ -669,7 +669,7 @@ static void nxagentDisplayBlockHandler(Display *display, int reason) ...@@ -669,7 +669,7 @@ static void nxagentDisplayBlockHandler(Display *display, int reason)
nxagentBlocking = 1; nxagentBlocking = 1;
if (SmartScheduleDisable == 1) if (!SmartScheduleSignalEnable)
{ {
/* /*
......
...@@ -116,36 +116,29 @@ Bool nxagentReconnectDisplay(void *p0); ...@@ -116,36 +116,29 @@ Bool nxagentReconnectDisplay(void *p0);
* Deal with the smart scheduler. * Deal with the smart scheduler.
*/ */
#if HAVE_SETITIMER
#define nxagentInitTimer() \ #define nxagentInitTimer() \
\ \
SmartScheduleInit(); SmartScheduleInit();
#define nxagentStopTimer() \ #define nxagentStopTimer() \
\ \
if (SmartScheduleTimerStopped == 0) \ SmartScheduleStopTimer(); \
{ \
SmartScheduleStopTimer(); \
} \
\
SmartScheduleIdle = 1;
#define nxagentStartTimer() \ #define nxagentStartTimer() \
\ \
if (SmartScheduleTimerStopped == 1) \ SmartScheduleStartTimer();
{ \
SmartScheduleStartTimer(); \
} \
\
SmartScheduleIdle = 0;
#define nxagentDisableTimer() \ #define nxagentDisableTimer() \
\ \
if (SmartScheduleTimerStopped == 0) \ SmartScheduleStopTimer(); \
{ \ SmartScheduleSignalEnable = FALSE;
SmartScheduleStopTimer(); \ #else
} \ #define nxagentInitTimer()
\ #define nxagentStopTimer()
SmartScheduleDisable = 1; #define nxagentStartTimer()
#define nxagentDisableTimer()
#endif /* HAVE_SETITIMER */
/* /*
* File descriptor currently used by * File descriptor currently used by
......
...@@ -597,7 +597,7 @@ void nxagentWakeupHandler(void * data, int count, void * mask) ...@@ -597,7 +597,7 @@ void nxagentWakeupHandler(void * data, int count, void * mask)
nxagentHandleConnectionStates(); nxagentHandleConnectionStates();
} }
if (SmartScheduleDisable == 1) if (!SmartScheduleSignalEnable)
{ {
#ifdef DEBUG #ifdef DEBUG
...@@ -885,7 +885,7 @@ void nxagentShadowWakeupHandler(void * data, int count, void * mask) ...@@ -885,7 +885,7 @@ void nxagentShadowWakeupHandler(void * data, int count, void * mask)
nxagentHandleConnectionStates(); nxagentHandleConnectionStates();
} }
if (SmartScheduleDisable == 1) if (!SmartScheduleSignalEnable)
{ {
#ifdef DEBUG #ifdef DEBUG
...@@ -1075,7 +1075,7 @@ void nxagentDispatchHandler(ClientPtr client, int in, int out) ...@@ -1075,7 +1075,7 @@ void nxagentDispatchHandler(ClientPtr client, int in, int out)
#endif #endif
} }
if (SmartScheduleDisable == 1) if (!SmartScheduleSignalEnable)
{ {
/* /*
...@@ -1150,7 +1150,7 @@ void nxagentDispatchHandler(ClientPtr client, int in, int out) ...@@ -1150,7 +1150,7 @@ void nxagentDispatchHandler(ClientPtr client, int in, int out)
* the inner dispatch loop forever. * the inner dispatch loop forever.
*/ */
if (SmartScheduleDisable == 1) if (!SmartScheduleSignalEnable)
{ {
if (client -> index != nxagentDispatch.client) if (client -> index != nxagentDispatch.client)
......
...@@ -387,7 +387,7 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio ...@@ -387,7 +387,7 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio
#endif #endif
if (nready && !SmartScheduleDisable) if (nready)
{ {
clientReady[0] = SmartScheduleClient (clientReady, nready); clientReady[0] = SmartScheduleClient (clientReady, nready);
nready = 1; nready = 1;
...@@ -422,8 +422,7 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio ...@@ -422,8 +422,7 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio
ProcessInputEvents(); ProcessInputEvents();
FlushIfCriticalOutputPending(); FlushIfCriticalOutputPending();
} }
if (!SmartScheduleDisable && if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice)
(SmartScheduleTime - start_tick) >= SmartScheduleSlice)
{ {
/* Penalize clients which consume ticks */ /* Penalize clients which consume ticks */
if (client->smart_priority > SMART_MIN_PRIORITY) if (client->smart_priority > SMART_MIN_PRIORITY)
...@@ -512,6 +511,10 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio ...@@ -512,6 +511,10 @@ Reply Total Cached Bits In Bits Out Bits/Reply Ratio
result = (* client->requestVector[MAJOROP])(client); result = (* client->requestVector[MAJOROP])(client);
#endif #endif
if (!SmartScheduleSignalEnable)
SmartScheduleTime = GetTimeInMillis();
if (result != Success) if (result != Success)
{ {
if (client->noClientException != Success) if (client->noClientException != Success)
......
...@@ -178,6 +178,13 @@ different from the user's real uid. ...@@ -178,6 +178,13 @@ different from the user's real uid.
.B \-core .B \-core
causes the server to generate a core dump on fatal errors. causes the server to generate a core dump on fatal errors.
.TP 8 .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 .B \-deferglyphs \fIwhichfonts\fP
specifies the types of fonts for which the server should attempt to use specifies the types of fonts for which the server should attempt to use
deferred glyph loading. \fIwhichfonts\fP can be all (all fonts), 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 ...@@ -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 client's backing store expectations but does not provide a way to tell
the client that it is doing so. the client that it is doing so.
.TP 8 .TP 8
.B \-x \fIextension\fP
loads the specified extension at init.
This is a no-op for most implementations.
.TP 8
.B [+-]xinerama .B [+-]xinerama
enables(+) or disables(-) XINERAMA provided via the PanoramiX extension. This is enables(+) or disables(-) XINERAMA provided via the PanoramiX extension. This is
set to off by default. set to off by default.
......
...@@ -16,6 +16,7 @@ depend:: ...@@ -16,6 +16,7 @@ depend::
InstallDriverSDKNonExecFile(XIstubs.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(XIstubs.h,$(DRIVERSDKINCLUDEDIR))
InstallDriverSDKNonExecFile(bstore.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(bstore.h,$(DRIVERSDKINCLUDEDIR))
InstallDriverSDKNonExecFile(bstorestr.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(bstorestr.h,$(DRIVERSDKINCLUDEDIR))
InstallDriverSDKNonExecFile(client.h,$(DRIVERSDKINCLUDEDIR))
InstallDriverSDKNonExecFile(colormap.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(colormap.h,$(DRIVERSDKINCLUDEDIR))
InstallDriverSDKNonExecFile(colormapst.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(colormapst.h,$(DRIVERSDKINCLUDEDIR))
InstallDriverSDKNonExecFile(cursor.h,$(DRIVERSDKINCLUDEDIR)) InstallDriverSDKNonExecFile(cursor.h,$(DRIVERSDKINCLUDEDIR))
......
/*
* 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 */
...@@ -24,6 +24,7 @@ SOFTWARE. ...@@ -24,6 +24,7 @@ SOFTWARE.
#ifndef DIXSTRUCT_H #ifndef DIXSTRUCT_H
#define DIXSTRUCT_H #define DIXSTRUCT_H
#include "client.h"
#include "dix.h" #include "dix.h"
#include "resource.h" #include "resource.h"
#include "cursor.h" #include "cursor.h"
...@@ -94,6 +95,7 @@ typedef struct _Client { ...@@ -94,6 +95,7 @@ typedef struct _Client {
void *requestBuffer; void *requestBuffer;
void *osPrivate; /* for OS layer, including scheduler */ void *osPrivate; /* for OS layer, including scheduler */
Bool swapped; Bool swapped;
Bool local;
ReplySwapPtr pSwapReplyFunc; ReplySwapPtr pSwapReplyFunc;
XID errorValue; XID errorValue;
int sequence; int sequence;
...@@ -141,6 +143,8 @@ typedef struct _Client { ...@@ -141,6 +143,8 @@ typedef struct _Client {
long smart_start_tick; long smart_start_tick;
long smart_stop_tick; long smart_stop_tick;
long smart_check_tick; long smart_check_tick;
ClientIdPtr clientIds;
} ClientRec; } ClientRec;
/* /*
...@@ -150,18 +154,19 @@ extern long SmartScheduleTime; ...@@ -150,18 +154,19 @@ extern long SmartScheduleTime;
extern long SmartScheduleInterval; extern long SmartScheduleInterval;
extern long SmartScheduleSlice; extern long SmartScheduleSlice;
extern long SmartScheduleMaxSlice; extern long SmartScheduleMaxSlice;
extern unsigned long SmartScheduleIdleCount; #ifdef HAVE_SETITIMER
extern Bool SmartScheduleDisable; #if HAVE_SETITIMER
extern Bool SmartScheduleIdle; extern Bool SmartScheduleSignalEnable;
extern Bool SmartScheduleTimerStopped; #else
extern Bool SmartScheduleStartTimer(void); #define SmartScheduleSignalEnable FALSE
#ifdef NXAGENT_SERVER #endif
extern Bool SmartScheduleStopTimer(void);
#endif #endif
extern void SmartScheduleStartTimer(void);
extern void SmartScheduleStopTimer(void);
#define SMART_MAX_PRIORITY (20) #define SMART_MAX_PRIORITY (20)
#define SMART_MIN_PRIORITY (-20) #define SMART_MIN_PRIORITY (-20)
extern Bool SmartScheduleInit(void); extern void SmartScheduleInit(void);
/* This prototype is used pervasively in Xext, dix */ /* This prototype is used pervasively in Xext, dix */
#define DISPATCH_PROC(func) int func(ClientPtr /* client */) #define DISPATCH_PROC(func) int func(ClientPtr /* client */)
......
...@@ -52,6 +52,8 @@ extern int defaultScreenSaverAllowExposures; ...@@ -52,6 +52,8 @@ extern int defaultScreenSaverAllowExposures;
extern int argcGlobal; extern int argcGlobal;
extern char **argvGlobal; extern char **argvGlobal;
extern char *display; extern char *display;
extern int displayfd;
extern Bool explicit_display;
extern int defaultBackingStore; extern int defaultBackingStore;
extern Bool disableBackingStore; extern Bool disableBackingStore;
...@@ -76,6 +78,6 @@ extern long maxBigRequestSize; ...@@ -76,6 +78,6 @@ extern long maxBigRequestSize;
extern Bool blackRoot; extern Bool blackRoot;
extern Bool CoreDump; extern Bool CoreDump;
extern Bool NoListenAll;
#endif /* OPAQUE_H */ #endif /* OPAQUE_H */
...@@ -120,6 +120,8 @@ extern void ResetOsBuffers(void); ...@@ -120,6 +120,8 @@ extern void ResetOsBuffers(void);
extern void InitConnectionLimits(void); extern void InitConnectionLimits(void);
extern void NotifyParentProcess(void);
extern void CreateWellKnownSockets(void); extern void CreateWellKnownSockets(void);
extern void ResetWellKnownSockets(void); extern void ResetWellKnownSockets(void);
...@@ -135,10 +137,6 @@ extern char *ClientAuthorized( ...@@ -135,10 +137,6 @@ extern char *ClientAuthorized(
unsigned int /*string_n*/, unsigned int /*string_n*/,
char* /*auth_string*/); char* /*auth_string*/);
extern Bool EstablishNewConnections(
ClientPtr /*clientUnused*/,
void * /*closure*/);
extern void CheckConnections(void); extern void CheckConnections(void);
extern void CloseDownConnection(ClientPtr /*client*/); extern void CloseDownConnection(ClientPtr /*client*/);
...@@ -317,10 +315,26 @@ typedef struct sockaddr * sockaddrPtr; ...@@ -317,10 +315,26 @@ typedef struct sockaddr * sockaddrPtr;
extern int InvalidHost(sockaddrPtr /*saddr*/, int /*len*/, ClientPtr client); extern int InvalidHost(sockaddrPtr /*saddr*/, int /*len*/, ClientPtr client);
extern int LocalClient(ClientPtr /* client */);
extern int LocalClientCred(ClientPtr, int *, int *); 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 ChangeAccessControl(ClientPtr /*client*/, int /*fEnabled*/);
extern int GetAccessControl(void); extern int GetAccessControl(void);
...@@ -506,6 +520,7 @@ typedef enum { ...@@ -506,6 +520,7 @@ typedef enum {
#endif #endif
extern const char *LogInit(const char *fname, const char *backup); extern const char *LogInit(const char *fname, const char *backup);
extern void LogSetDisplay(void);
extern void LogClose(void); extern void LogClose(void);
extern Bool LogSetParameter(LogParameter param, int value); extern Bool LogSetParameter(LogParameter param, int value);
extern void LogVWrite(int verb, const char *f, va_list args); extern void LogVWrite(int verb, const char *f, va_list args);
......
...@@ -25,25 +25,31 @@ ...@@ -25,25 +25,31 @@
#include <Server.tmpl> #include <Server.tmpl>
NULL =
/* /*
* If you have any extra files to be put into the library, define them here. * If you have any extra files to be put into the library, define them here.
*/ */
ZONEID_DEFINES = -UHAVE_GETZONEID
#if NXLibraries #if NXLibraries
NX_INCLUDES = -I../../../../nxcomp NX_INCLUDES = -I../../../../nxcomp
NX_DEFINES = -DNX_TRANS_SOCKET \ NX_DEFINES = -DNX_TRANS_SOCKET \
-DNX_TRANS_AUTH \ -DNX_TRANS_AUTH \
-DNX_TRANS_FOPEN \ -DNX_TRANS_FOPEN \
-DNX_TRANS_SLEEP \ -DNX_TRANS_SLEEP \
-DNX_TRANS_EXIT \ -DNX_TRANS_EXIT \
-DNX_TRANS_WAKEUP=1000 -DNX_TRANS_WAKEUP=1000 \
-DNXAGENT_SERVER \
$(NULL)
# -DNX_TRANS_WARN \ # -DNX_TRANS_WARN \
# -DNX_TRANS_INFO \ # -DNX_TRANS_INFO \
# -DNX_TRANS_TEST \ # -DNX_TRANS_TEST \
# -DNX_TRANS_DEBUG \ # -DNX_TRANS_DEBUG \
#endif #endif
...@@ -121,16 +127,53 @@ TMEMCMP_OBJS = timingsafe_memcmp.o ...@@ -121,16 +127,53 @@ TMEMCMP_OBJS = timingsafe_memcmp.o
#endif #endif
BOOTSTRAPCFLAGS = BOOTSTRAPCFLAGS =
SRCS = WaitFor.c access.c connection.c io.c $(COLOR_SRCS) \ SRCS = WaitFor.c \
osinit.c utils.c log.c auth.c mitauth.c secauth.c \ access.c \
$(XDMAUTHSRCS) $(RPCSRCS) xdmcp.c OtherSources \ client.c \
xstrans.c $(SNPRINTF_SRCS) $(STRLCAT_SRCS) \ connection.c \
$(REALLOCARRAY_SRCS) xprintf.c $(TMEMCMP_SRCS) io.c \
OBJS = WaitFor.o access.o connection.o io.o $(COLOR_OBJS) \ $(COLOR_SRCS) \
osinit.o utils.o log.o auth.o mitauth.o secauth.o \ osinit.c \
$(XDMAUTHOBJS) $(RPCOBJS) xdmcp.o OtherObjects \ utils.c \
xstrans.o $(SNPRINTF_OBJS) $(STRLCAT_OBJS) \ log.c \
$(REALLOCARRAY_OBJS) xprintf.o $(TMEMCMP_OBJS) 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 #if UseMemLeak
MEM_DEFINES = -DMEMBUG MEM_DEFINES = -DMEMBUG
...@@ -143,18 +186,39 @@ BOOTSTRAPCFLAGS = ...@@ -143,18 +186,39 @@ BOOTSTRAPCFLAGS =
#endif #endif
XTRANS_DEFINES = -DXTRANS_SEND_FDS=0 XTRANS_DEFINES = -DXTRANS_SEND_FDS=0
DEFINES = $(CONNECTION_FLAGS) $(MEM_DEFINES) \ DEFINES = $(CONNECTION_FLAGS) \
$(XDMAUTHDEFS) $(RPCDEFS) $(SIGNAL_DEFINES) $(OS_DEFINES) \ $(MEM_DEFINES) \
$(GETPEER_DEFINES) \ $(XDMAUTHDEFS) \
$(RANDOM_DEFINES) $(BUGMSG) $(XTRANS_FAILDEFINES) \ $(RPCDEFS) \
$(XTRANS_DEFINES) $(NX_DEFINES) $(SIGNAL_DEFINES) \
INCLUDES = -I. -I../include -I$(XINCLUDESRC) -I$(EXTINCSRC) \ $(OS_DEFINES) \
-I$(SERVERSRC)/Xext -I$(SERVERSRC)/render \ $(GETPEER_DEFINES) \
-I$(TOP)/lib/Xau $(NX_INCLUDES) \ $(RANDOM_DEFINES) \
`pkg-config --cflags-only-I pixman-1` $(BUGMSG) \
DEPEND_DEFINES = $(XDMCP_DEFINES) $(EXT_DEFINES) \ $(XTRANS_FAILDEFINES) \
$(TRANS_INCLUDES) $(CONNECTION_FLAGS) $(GETPEER_DEFINES) \ $(XTRANS_DEFINES) \
DependDefines $(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 LINTLIBS = ../dix/llib-ldix.ln
#ifdef NEED_ALLOCA_FROM_LIBPW #ifdef NEED_ALLOCA_FROM_LIBPW
...@@ -176,7 +240,7 @@ alloca.o: $(PWLIB) ...@@ -176,7 +240,7 @@ alloca.o: $(PWLIB)
ar x $(PWLIB) alloca.o ar x $(PWLIB) alloca.o
#endif /* NEED_ALLOCA_FROM_LIBPW */ #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(auth,$(ICONFIGFILES),$(XDMCP_DEFINES))
SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES)) SpecialCObjectRule(xdmauth,$(ICONFIGFILES),$(XDMCP_DEFINES))
SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES)) SpecialCObjectRule(xdmcp,$(ICONFIGFILES),$(SOCK_DEFINES) $(XDMCP_DEFINES))
......
...@@ -213,18 +213,10 @@ WaitForSomething(int *pClientsReady) ...@@ -213,18 +213,10 @@ WaitForSomething(int *pClientsReady)
ProcessWorkQueue(); ProcessWorkQueue();
if (XFD_ANYSET (&ClientsWithInput)) if (XFD_ANYSET (&ClientsWithInput))
{ {
if (!SmartScheduleDisable) someReady = TRUE;
{ waittime.tv_sec = 0;
someReady = TRUE; waittime.tv_usec = 0;
waittime.tv_sec = 0; wt = &waittime;
waittime.tv_usec = 0;
wt = &waittime;
}
else
{
XFD_COPYSET (&ClientsWithInput, &clientsReadable);
break;
}
} }
if (someReady) if (someReady)
{ {
...@@ -247,7 +239,8 @@ WaitForSomething(int *pClientsReady) ...@@ -247,7 +239,8 @@ WaitForSomething(int *pClientsReady)
} }
XFD_COPYSET(&AllSockets, &LastSelectMask); XFD_COPYSET(&AllSockets, &LastSelectMask);
} }
SmartScheduleIdle = TRUE; SmartScheduleStopTimer ();
BlockHandler((void *)&wt, (void *)&LastSelectMask); BlockHandler((void *)&wt, (void *)&LastSelectMask);
if (NewOutputPending) if (NewOutputPending)
FlushAllOutput(); FlushAllOutput();
...@@ -387,13 +380,8 @@ WaitForSomething(int *pClientsReady) ...@@ -387,13 +380,8 @@ WaitForSomething(int *pClientsReady)
i = XTestProcessInputAction (i, &waittime); i = XTestProcessInputAction (i, &waittime);
} }
#endif /* XTESTEXT1 */ #endif /* XTESTEXT1 */
if (i >= 0) SmartScheduleStartTimer ();
{
SmartScheduleIdle = FALSE;
SmartScheduleIdleCount = 0;
if (SmartScheduleTimerStopped)
(void) SmartScheduleStartTimer ();
}
if (i <= 0) /* An error or timeout occurred */ if (i <= 0) /* An error or timeout occurred */
{ {
#if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG) #if defined(NX_TRANS_SOCKET) && defined(NX_TRANS_DEBUG)
...@@ -507,10 +495,6 @@ WaitForSomething(int *pClientsReady) ...@@ -507,10 +495,6 @@ WaitForSomething(int *pClientsReady)
} }
XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients); 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); XFD_ANDSET(&tmp_set, &LastSelectMask, &NotifyReadFds);
if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady) if (XFD_ANYSET(&tmp_set) || someNotifyWriteReady)
...@@ -544,17 +528,14 @@ WaitForSomething(int *pClientsReady) ...@@ -544,17 +528,14 @@ WaitForSomething(int *pClientsReady)
#ifndef WIN32 #ifndef WIN32
for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++) for (i=0; i<howmany(XFD_SETSIZE, NFDBITS); i++)
{ {
int highest_priority = 0;
while (clientsReadable.fds_bits[i]) while (clientsReadable.fds_bits[i])
{ {
int client_priority, client_index; int client_index;
curclient = ffs (clientsReadable.fds_bits[i]) - 1; curclient = ffs (clientsReadable.fds_bits[i]) - 1;
client_index = /* raphael: modified */ client_index = /* raphael: modified */
ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))]; ConnectionTranslation[curclient + (i * (sizeof(fd_mask) * 8))];
#else #else
int highest_priority = 0;
fd_set savedClientsReadable; fd_set savedClientsReadable;
XFD_COPYSET(&clientsReadable, &savedClientsReadable); XFD_COPYSET(&clientsReadable, &savedClientsReadable);
for (i = 0; i < XFD_SETCOUNT(&savedClientsReadable); i++) for (i = 0; i < XFD_SETCOUNT(&savedClientsReadable); i++)
...@@ -564,40 +545,10 @@ WaitForSomething(int *pClientsReady) ...@@ -564,40 +545,10 @@ WaitForSomething(int *pClientsReady)
curclient = XFD_FD(&savedClientsReadable, i); curclient = XFD_FD(&savedClientsReadable, i);
client_index = GetConnectionTranslation(curclient); client_index = GetConnectionTranslation(curclient);
#endif #endif
#ifdef XSYNC pClientsReady[nready++] = client_index;
/* 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;
}
#ifndef WIN32 #ifndef WIN32
clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient); clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient);
} }
#else #else
FD_CLR(curclient, &clientsReadable); FD_CLR(curclient, &clientsReadable);
#endif #endif
......
...@@ -204,10 +204,6 @@ static Bool NewHost(int /*family*/, ...@@ -204,10 +204,6 @@ static Bool NewHost(int /*family*/,
int /*len*/, int /*len*/,
int /* addingLocalHosts */); 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 /* 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, /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 and a LocalHostRequested variable. These default to FALSE, but are set
...@@ -496,7 +492,7 @@ DefineSelf (int fd) ...@@ -496,7 +492,7 @@ DefineSelf (int fd)
void void
DefineSelf (int fd) DefineSelf (int fd)
{ {
#if !defined(TCPCONN) && !defined(UNIXCONN) && !defined(MNX_TCPCONN) #if !defined(TCPCONN) && !defined(UNIXCONN)
return; return;
#else #else
register int n; register int n;
...@@ -631,7 +627,7 @@ DefineLocalHost: ...@@ -631,7 +627,7 @@ DefineLocalHost:
selfhosts = host; selfhosts = host;
} }
} }
#endif /* !TCPCONN && !UNIXCONN && !MNX_TCPCONN */ #endif /* !TCPCONN && !UNIXCONN */
} }
#else #else
...@@ -893,6 +889,8 @@ DefineSelf (int fd) ...@@ -893,6 +889,8 @@ DefineSelf (int fd)
return; return;
} }
for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) { for (ifr = ifap; ifr != NULL; ifr = ifr->ifa_next) {
if (!ifr->ifa_addr)
continue;
len = sizeof(*(ifr->ifa_addr)); len = sizeof(*(ifr->ifa_addr));
family = ConvertAddr(ifr->ifa_addr, &len, (void **)&addr); family = ConvertAddr(ifr->ifa_addr, &len, (void **)&addr);
if (family == -1 || family == FamilyLocal) if (family == -1 || family == FamilyLocal)
...@@ -1068,11 +1066,10 @@ ResetHosts (char *display) ...@@ -1068,11 +1066,10 @@ ResetHosts (char *display)
FILE *fd; FILE *fd;
char *ptr; char *ptr;
int i, hostlen; int i, hostlen;
#if ((defined(TCPCONN) || defined(MNX_TCPCONN)) && \ #if (defined(TCPCONN) && (!defined(IPv6) || !defined(AF_INET6)))
(!defined(IPv6) || !defined(AF_INET6)))
union { union {
struct sockaddr sa; struct sockaddr sa;
#if defined(TCPCONN) || defined(MNX_TCPCONN) #if defined(TCPCONN)
struct sockaddr_in in; struct sockaddr_in in;
#endif /* TCPCONN */ #endif /* TCPCONN */
} saddr; } saddr;
...@@ -1117,7 +1114,7 @@ ResetHosts (char *display) ...@@ -1117,7 +1114,7 @@ ResetHosts (char *display)
NewHost(family, "", 0, FALSE); NewHost(family, "", 0, FALSE);
LocalHostRequested = TRUE; /* Fix for XFree86 bug #156 */ LocalHostRequested = TRUE; /* Fix for XFree86 bug #156 */
} }
#if defined(TCPCONN) || defined(MNX_TCPCONN) #if defined(TCPCONN)
else if (!strncmp("inet:", lhostname, 5)) else if (!strncmp("inet:", lhostname, 5))
{ {
family = FamilyInternet; family = FamilyInternet;
...@@ -1162,7 +1159,7 @@ ResetHosts (char *display) ...@@ -1162,7 +1159,7 @@ ResetHosts (char *display)
} }
else else
#endif /* SECURE_RPC */ #endif /* SECURE_RPC */
#if defined(TCPCONN) || defined(MNX_TCPCONN) #if defined(TCPCONN)
{ {
#if defined(IPv6) && defined(AF_INET6) #if defined(IPv6) && defined(AF_INET6)
if ( (family == FamilyInternet) || (family == FamilyInternet6) || if ( (family == FamilyInternet) || (family == FamilyInternet6) ||
...@@ -1220,12 +1217,17 @@ ResetHosts (char *display) ...@@ -1220,12 +1217,17 @@ ResetHosts (char *display)
} }
/* Is client on the local host */ /* Is client on the local host */
Bool LocalClient(ClientPtr client) Bool
ComputeLocalClient(ClientPtr client)
{ {
int alen, family, notused; int alen, family, notused;
Xtransaddr *from = NULL; Xtransaddr *from = NULL;
void *addr; void *addr;
register HOST *host; register HOST *host;
OsCommPtr oc = (OsCommPtr) client->osPrivate;
if (!oc->trans_conn)
return FALSE;
#ifdef XCSECURITY #ifdef XCSECURITY
/* untrusted clients can't change host access */ /* untrusted clients can't change host access */
...@@ -1236,65 +1238,79 @@ Bool LocalClient(ClientPtr client) ...@@ -1236,65 +1238,79 @@ Bool LocalClient(ClientPtr client)
return FALSE; return FALSE;
} }
#endif #endif
if (!_XSERVTransGetPeerAddr (((OsCommPtr)client->osPrivate)->trans_conn, if (!_XSERVTransGetPeerAddr (oc->trans_conn, &notused, &alen, &from))
&notused, &alen, &from))
{ {
family = ConvertAddr ((struct sockaddr *) from, family = ConvertAddr ((struct sockaddr *) from,
&alen, (void **)&addr); &alen, (void **)&addr);
if (family == -1) if (family == -1)
{ {
free ((char *) from); free(from);
return FALSE; return FALSE;
} }
if (family == FamilyLocal) if (family == FamilyLocal)
{ {
free ((char *) from); free(from);
return TRUE; return TRUE;
} }
for (host = selfhosts; host; host = host->next) for (host = selfhosts; host; host = host->next)
{ {
if (addrEqual (family, addr, alen, host)) if (addrEqual (family, addr, alen, host)) {
free(from);
return TRUE; return TRUE;
}
} }
free ((char *) from); free(from);
} }
return FALSE; return FALSE;
} }
/* /*
* Return the uid and gid of a connected local client * Return the uid and gid of a connected local client
* or the uid/gid for nobody those ids cannot be determined
* *
* Used by XShm to test access rights to shared memory segments * Used by XShm to test access rights to shared memory segments
*/ */
int int
LocalClientCred(ClientPtr client, int *pUid, int *pGid) 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 * 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 localuser & localgroup ServerInterpreted access control forms below
* Used by AuthAudit to log where local connections came from
*/ */
int int
LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, GetLocalClientCreds(ClientPtr client, LocalClientCredRec **lccp)
int **pSuppGids, int *nSuppGids)
{ {
#if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED) #if defined(HAS_GETPEEREID) || defined(HAS_GETPEERUCRED) || defined(SO_PEERCRED)
int fd; int fd;
XtransConnInfo ci; XtransConnInfo ci;
LocalClientCredRec *lcc;
#ifdef HAS_GETPEEREID #ifdef HAS_GETPEEREID
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
#elif defined(HAS_GETPEERUCRED) #elif defined(HAS_GETPEERUCRED)
ucred_t *peercred = NULL; ucred_t *peercred = NULL;
const gid_t *gids;
#elif defined(SO_PEERCRED) #elif defined(SO_PEERCRED)
struct ucred peercred; struct ucred peercred;
socklen_t so_len = sizeof(peercred); socklen_t so_len = sizeof(peercred);
...@@ -1313,57 +1329,64 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, ...@@ -1313,57 +1329,64 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
} }
#endif #endif
if (pSuppGids != NULL) *lccp = calloc(1, sizeof(LocalClientCredRec));
*pSuppGids = NULL; if (*lccp == NULL)
if (nSuppGids != NULL) return -1;
*nSuppGids = 0; lcc = *lccp;
fd = _XSERVTransGetConnectionNumber(ci); fd = _XSERVTransGetConnectionNumber(ci);
#ifdef HAS_GETPEEREID #ifdef HAS_GETPEEREID
if (getpeereid(fd, &uid, &gid) == -1) if (getpeereid(fd, &uid, &gid) == -1) {
return -1; FreeLocalClientCreds(lcc);
if (pUid != NULL) return -1;
*pUid = uid; }
if (pGid != NULL) lcc->euid = uid;
*pGid = gid; lcc->egid = gid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET;
return 0; return 0;
#elif defined(HAS_GETPEERUCRED) #elif defined(HAS_GETPEERUCRED)
if (getpeerucred(fd, &peercred) < 0) if (getpeerucred(fd, &peercred) < 0) {
return -1; FreeLocalClientCreds(lcc);
#ifdef sun /* Ensure process is in the same zone */
if (getzoneid() != ucred_getzoneid(peercred)) {
ucred_free(peercred);
return -1; return -1;
} lcc->euid = ucred_geteuid(peercred);
#endif if (lcc->euid != -1)
if (pUid != NULL) lcc->fieldsSet |= LCC_UID_SET;
*pUid = ucred_geteuid(peercred); lcc->egid = ucred_getegid(peercred);
if (pGid != NULL) if (lcc->egid != -1)
*pGid = ucred_getegid(peercred); lcc->fieldsSet |= LCC_GID_SET;
if (pSuppGids != NULL && nSuppGids != NULL) { lcc->pid = ucred_getpid(peercred);
const gid_t *gids; if (lcc->pid != -1)
*nSuppGids = ucred_getgroups(peercred, &gids); lcc->fieldsSet |= LCC_PID_SET;
if (*nSuppGids > 0) { #ifdef HAVE_GETZONEID
*pSuppGids = malloc(sizeof(int) * (*nSuppGids)); lcc->zoneid = ucred_getzoneid(peercred);
if (*pSuppGids == NULL) { if (lcc->zoneid != -1)
*nSuppGids = 0; lcc->fieldsSet |= LCC_ZID_SET;
} else { #endif
int i; lcc->nSuppGids = ucred_getgroups(peercred, &gids);
for (i = 0 ; i < *nSuppGids; i++) { if (lcc->nSuppGids > 0) {
(*pSuppGids)[i] = (int) gids[i]; 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); ucred_free(peercred);
return 0; return 0;
#elif defined(SO_PEERCRED) #elif defined(SO_PEERCRED)
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) == -1) {
return -1; FreeLocalClientCreds(lcc);
if (pUid != NULL) return -1;
*pUid = peercred.uid; }
if (pGid != NULL) lcc->euid = peercred.uid;
*pGid = peercred.gid; lcc->egid = peercred.gid;
lcc->pid = peercred.pid;
lcc->fieldsSet = LCC_UID_SET | LCC_GID_SET | LCC_PID_SET;
return 0; return 0;
#endif #endif
#else #else
...@@ -1373,12 +1396,23 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid, ...@@ -1373,12 +1396,23 @@ LocalClientCredAndGroups(ClientPtr client, int *pUid, int *pGid,
#endif #endif
} }
void
FreeLocalClientCreds(LocalClientCredRec *lcc)
{
if (lcc != NULL) {
if (lcc->nSuppGids > 0) {
free(lcc->pSuppGids);
}
free(lcc);
}
}
static Bool static Bool
AuthorizedClient(ClientPtr client) AuthorizedClient(ClientPtr client)
{ {
if (!client || defeatAccessControl) if (!client || defeatAccessControl)
return TRUE; return TRUE;
return LocalClient(client); return client->local ? Success : BadAccess;
} }
/* Add a host to the access control list. This is the external interface /* Add a host to the access control list. This is the external interface
...@@ -1593,7 +1627,7 @@ CheckAddr ( ...@@ -1593,7 +1627,7 @@ CheckAddr (
switch (family) switch (family)
{ {
#if defined(TCPCONN) || defined(MNX_TCPCONN) #if defined(TCPCONN)
case FamilyInternet: case FamilyInternet:
if (length == sizeof (struct in_addr)) if (length == sizeof (struct in_addr))
len = length; len = length;
...@@ -1686,7 +1720,7 @@ ConvertAddr ( ...@@ -1686,7 +1720,7 @@ ConvertAddr (
case AF_UNIX: case AF_UNIX:
#endif #endif
return FamilyLocal; return FamilyLocal;
#if defined(TCPCONN) || defined(MNX_TCPCONN) #if defined(TCPCONN)
case AF_INET: case AF_INET:
#ifdef WIN32 #ifdef WIN32
if (16777343 == *(long*)&((struct sockaddr_in *) saddr)->sin_addr) if (16777343 == *(long*)&((struct sockaddr_in *) saddr)->sin_addr)
...@@ -2176,38 +2210,48 @@ static Bool ...@@ -2176,38 +2210,48 @@ static Bool
siLocalCredAddrMatch(int family, void * addr, int len, siLocalCredAddrMatch(int family, void * addr, int len,
const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv) const char *siAddr, int siAddrlen, ClientPtr client, void *typePriv)
{ {
int connUid, connGid, *connSuppGids, connNumSuppGids, siAddrId; int siAddrId;
LocalClientCredRec *lcc;
siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv; siLocalCredPrivPtr lcPriv = (siLocalCredPrivPtr) typePriv;
if (LocalClientCredAndGroups(client, &connUid, &connGid, if (GetLocalClientCreds(client, &lcc) == -1) {
&connSuppGids, &connNumSuppGids) == -1) {
return FALSE; 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) { if (siLocalCredGetId(siAddr, siAddrlen, lcPriv, &siAddrId) == FALSE) {
FreeLocalClientCreds(lcc);
return FALSE; return FALSE;
} }
if (lcPriv->credType == LOCAL_USER) { if (lcPriv->credType == LOCAL_USER) {
if (connUid == siAddrId) { if ((lcc->fieldsSet & LCC_UID_SET) && (lcc->euid == siAddrId)) {
FreeLocalClientCreds(lcc);
return TRUE; return TRUE;
} }
} else { } else {
if (connGid == siAddrId) { if ((lcc->fieldsSet & LCC_GID_SET) && (lcc->egid == siAddrId)) {
FreeLocalClientCreds(lcc);
return TRUE; return TRUE;
} }
if (connSuppGids != NULL) { if (lcc->pSuppGids != NULL) {
int i; int i;
for (i = 0 ; i < connNumSuppGids; i++) { for (i = 0 ; i < lcc->nSuppGids; i++) {
if (connSuppGids[i] == siAddrId) { if (lcc->pSuppGids[i] == siAddrId) {
free(connSuppGids); FreeLocalClientCreds(lcc);
return TRUE; return TRUE;
} }
} }
free(connSuppGids);
} }
} }
FreeLocalClientCreds(lcc);
return FALSE; return FALSE;
} }
......
/*
* 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;
}
...@@ -74,6 +74,7 @@ SOFTWARE. ...@@ -74,6 +74,7 @@ SOFTWARE.
#define TRANS_SERVER #define TRANS_SERVER
#define TRANS_REOPEN #define TRANS_REOPEN
#include <nx-X11/Xtrans/Xtrans.h> #include <nx-X11/Xtrans/Xtrans.h>
#include <nx-X11/Xtrans/Xtransint.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
...@@ -122,7 +123,6 @@ SOFTWARE. ...@@ -122,7 +123,6 @@ SOFTWARE.
int lastfdesc; /* maximum file descriptor */ int lastfdesc; /* maximum file descriptor */
fd_set WellKnownConnections; /* Listener mask */
fd_set NotifyReadFds; /* mask for other file descriptors */ fd_set NotifyReadFds; /* mask for other file descriptors */
fd_set NotifyWriteFds; /* mask for other write file descriptors */ fd_set NotifyWriteFds; /* mask for other write file descriptors */
fd_set AllSockets; /* select on this */ fd_set AllSockets; /* select on this */
...@@ -136,7 +136,9 @@ int MaxClients = 0; ...@@ -136,7 +136,9 @@ int MaxClients = 0;
int NumNotifyWriteFd; /* Number of NotifyFd members with write set */ int NumNotifyWriteFd; /* Number of NotifyFd members with write set */
Bool NewOutputPending; /* not yet attempted to write some new output */ Bool NewOutputPending; /* not yet attempted to write some new output */
Bool AnyWritesPending; /* true if some client blocked on write or NotifyFd with write */ 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 */ Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
static char dynamic_display[7]; /* display name */
Bool PartialNetwork; /* continue even if unable to bind all addrs */ Bool PartialNetwork; /* continue even if unable to bind all addrs */
static Pid_t ParentProcess; static Pid_t ParentProcess;
...@@ -149,6 +151,9 @@ static fd_set SavedAllSockets; ...@@ -149,6 +151,9 @@ static fd_set SavedAllSockets;
static fd_set SavedClientsWithInput; static fd_set SavedClientsWithInput;
int GrabInProgress = 0; int GrabInProgress = 0;
static void
QueueNewConnections(int curconn, int ready, void *data);
#if !defined(WIN32) #if !defined(WIN32)
int *ConnectionTranslation = NULL; int *ConnectionTranslation = NULL;
#else #else
...@@ -319,6 +324,72 @@ InitConnectionLimits(void) ...@@ -319,6 +324,72 @@ InitConnectionLimits(void)
#endif #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 * CreateWellKnownSockets
...@@ -330,8 +401,6 @@ CreateWellKnownSockets(void) ...@@ -330,8 +401,6 @@ CreateWellKnownSockets(void)
{ {
int i; int i;
int partial; int partial;
char port[20];
OsSigHandlerPtr handler;
FD_ZERO(&AllSockets); FD_ZERO(&AllSockets);
FD_ZERO(&AllClients); FD_ZERO(&AllClients);
...@@ -344,38 +413,47 @@ CreateWellKnownSockets(void) ...@@ -344,38 +413,47 @@ CreateWellKnownSockets(void)
ClearConnectionTranslation(); ClearConnectionTranslation();
#endif #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, for (i = 0; i < ListenTransCount; i++) {
&ListenTransCount, &ListenTransConns) >= 0) && int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
(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++) ListenTransFds[i] = fd;
{ SetNotifyFd(fd, QueueNewConnections, X_NOTIFY_READ, NULL);
int fd = _XSERVTransGetConnectionNumber (ListenTransConns[i]);
if (!_XSERVTransIsLocal(ListenTransConns[i]))
ListenTransFds[i] = fd; DefineSelf (fd);
FD_SET (fd, &WellKnownConnections);
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"); FatalError ("Cannot establish any listening sockets - Make sure an X server isn't already running");
#if !defined(WIN32) #if !defined(WIN32)
OsSignal (SIGPIPE, SIG_IGN); OsSignal (SIGPIPE, SIG_IGN);
...@@ -383,35 +461,10 @@ CreateWellKnownSockets(void) ...@@ -383,35 +461,10 @@ CreateWellKnownSockets(void)
#endif #endif
OsSignal (SIGINT, GiveUp); OsSignal (SIGINT, GiveUp);
OsSignal (SIGTERM, GiveUp); OsSignal (SIGTERM, GiveUp);
XFD_COPYSET (&WellKnownConnections, &AllSockets);
ResetHosts(display); ResetHosts(display);
/*
* Magic: If SIGUSR1 was set to SIG_IGN when InitParentProcess();
* 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
#ifdef XDMCP #ifdef XDMCP
XdmcpInit (); XdmcpInit ();
#endif #endif
...@@ -476,7 +529,7 @@ ResetWellKnownSockets (void) ...@@ -476,7 +529,7 @@ ResetWellKnownSockets (void)
* Remove it from out list. * Remove it from out list.
*/ */
FD_CLR (ListenTransFds[i], &WellKnownConnections); RemoveNotifyFd(ListenTransFds[i]);
ListenTransFds[i] = ListenTransFds[ListenTransCount - 1]; ListenTransFds[i] = ListenTransFds[ListenTransCount - 1];
ListenTransConns[i] = ListenTransConns[ListenTransCount - 1]; ListenTransConns[i] = ListenTransConns[ListenTransCount - 1];
ListenTransCount -= 1; ListenTransCount -= 1;
...@@ -490,26 +543,17 @@ ResetWellKnownSockets (void) ...@@ -490,26 +543,17 @@ ResetWellKnownSockets (void)
int newfd = _XSERVTransGetConnectionNumber (ListenTransConns[i]); int newfd = _XSERVTransGetConnectionNumber (ListenTransConns[i]);
FD_CLR (ListenTransFds[i], &WellKnownConnections);
ListenTransFds[i] = newfd; ListenTransFds[i] = newfd;
FD_SET(newfd, &WellKnownConnections);
} }
} }
} }
for (i = 0; i < ListenTransCount; i++)
SetNotifyFd(ListenTransFds[i], QueueNewConnections, X_NOTIFY_READ, NULL);
ResetAuthorization (); ResetAuthorization ();
ResetHosts(display); ResetHosts(display);
/* /*
* See above in CreateWellKnownSockets about SIGUSR1
*/
#if !defined(WIN32)
if (RunFromSmartParent) {
if (ParentProcess > 1) {
kill (ParentProcess, SIGUSR1);
}
}
#endif
/*
* restart XDMCP * restart XDMCP
*/ */
#ifdef XDMCP #ifdef XDMCP
...@@ -522,8 +566,15 @@ CloseWellKnownConnections(void) ...@@ -522,8 +566,15 @@ CloseWellKnownConnections(void)
{ {
int i; int i;
for (i = 0; i < ListenTransCount; i++) for (i = 0; i < ListenTransCount; i++) {
_XSERVTransClose (ListenTransConns[i]); if (ListenTransConns[i] != NULL) {
_XSERVTransClose(ListenTransConns[i]);
ListenTransConns[i] = NULL;
if (ListenTransFds != NULL)
RemoveNotifyFd(ListenTransFds[i]);
}
}
ListenTransCount = 0;
} }
static void static void
...@@ -534,10 +585,9 @@ AuthAudit (ClientPtr client, Bool letin, ...@@ -534,10 +585,9 @@ AuthAudit (ClientPtr client, Bool letin,
char addr[128]; char addr[128];
char *out = addr; char *out = addr;
if (!((OsCommPtr)client->osPrivate)->trans_conn) { char client_uid_string[64];
strcpy(addr, "LBX proxy at "); LocalClientCredRec *lcc;
out += strlen(addr);
}
if (!len) if (!len)
strcpy(out, "local host"); strcpy(out, "local host");
else else
...@@ -549,7 +599,7 @@ AuthAudit (ClientPtr client, Bool letin, ...@@ -549,7 +599,7 @@ AuthAudit (ClientPtr client, Bool letin,
#endif #endif
strcpy(out, "local host"); strcpy(out, "local host");
break; break;
#if defined(TCPCONN) || defined(MNX_TCPCONN) #if defined(TCPCONN)
case AF_INET: case AF_INET:
sprintf(out, "IP %s", sprintf(out, "IP %s",
inet_ntoa(((struct sockaddr_in *) saddr)->sin_addr)); inet_ntoa(((struct sockaddr_in *) saddr)->sin_addr));
...@@ -567,14 +617,56 @@ AuthAudit (ClientPtr client, Bool letin, ...@@ -567,14 +617,56 @@ AuthAudit (ClientPtr client, Bool letin,
default: default:
strcpy(out, "unknown address"); 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) 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, client->index, letin ? "connected" : "rejected", addr,
(int)proto_n, auth_proto, auth_id); client_uid_string, (int)proto_n, auth_proto, auth_id);
else else
AuditF("client %d %s from %s\n", AuditF("client %d %s from %s%s\n",
client->index, letin ? "connected" : "rejected", addr); client->index, letin ? "connected" : "rejected", addr,
client_uid_string);
} }
XID XID
...@@ -713,6 +805,7 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) ...@@ -713,6 +805,7 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time)
free (oc); free (oc);
return NullClient; return NullClient;
} }
client->local = ComputeLocalClient(client);
{ {
#if !defined(WIN32) #if !defined(WIN32)
ConnectionTranslation[fd] = client->index; ConnectionTranslation[fd] = client->index;
...@@ -746,23 +839,18 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time) ...@@ -746,23 +839,18 @@ AllocNewConnection (XtransConnInfo trans_conn, int fd, CARD32 conn_time)
* and AllSockets. * and AllSockets.
*****************/ *****************/
/*ARGSUSED*/ static Bool
Bool
EstablishNewConnections(ClientPtr clientUnused, void * closure) EstablishNewConnections(ClientPtr clientUnused, void * closure)
{ {
fd_set readyconnections; /* set of listeners that are ready */ int curconn = (int) (intptr_t) closure;
int curconn; /* fd of listener that's ready */ int newconn; /* fd of new client */
register int newconn; /* fd of new client */
CARD32 connect_time; CARD32 connect_time;
register int i; int i;
register ClientPtr client; ClientPtr client;
register OsCommPtr oc; OsCommPtr oc;
fd_set tmask; XtransConnInfo trans_conn, new_trans_conn;
int status;
XFD_ANDSET (&tmask, (fd_set*)closure, &WellKnownConnections);
XFD_COPYSET(&tmask, &readyconnections);
if (!XFD_ANYSET(&readyconnections))
return TRUE;
connect_time = GetTimeInMillis(); connect_time = GetTimeInMillis();
/* kill off stragglers */ /* kill off stragglers */
for (i=1; i<currentMaxClients; i++) for (i=1; i<currentMaxClients; i++)
...@@ -776,60 +864,44 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure) ...@@ -776,60 +864,44 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure)
CloseDownClient(client); CloseDownClient(client);
} }
} }
#ifndef WIN32 if ((trans_conn = lookup_trans_conn(curconn)) == NULL)
for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) return TRUE;
{
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) if ((new_trans_conn = _XSERVTransAccept(trans_conn, &status)) == NULL)
continue; return TRUE;
if ((new_trans_conn = _XSERVTransAccept (trans_conn, &status)) == NULL) newconn = _XSERVTransGetConnectionNumber(new_trans_conn);
continue;
newconn = _XSERVTransGetConnectionNumber (new_trans_conn); if (newconn < lastfdesc) {
int clientid;
if (newconn < lastfdesc)
{
int clientid;
#if !defined(WIN32) #if !defined(WIN32)
clientid = ConnectionTranslation[newconn]; clientid = ConnectionTranslation[newconn];
#else #else
clientid = GetConnectionTranslation(newconn); clientid = GetConnectionTranslation(newconn);
#endif #endif
if(clientid && (client = clients[clientid])) if (clientid && (client = clients[clientid]))
CloseDownClient(client); 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; 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" #define NOROOM "Maximum number of clients reached"
/************ /************
...@@ -838,35 +910,28 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure) ...@@ -838,35 +910,28 @@ EstablishNewConnections(ClientPtr clientUnused, void * closure)
************/ ************/
static void static void
ErrorConnMax(XtransConnInfo trans_conn) ConnMaxNotify(int fd, int events, void *data)
{ {
int fd = _XSERVTransGetConnectionNumber (trans_conn); XtransConnInfo trans_conn = data;
xConnSetupPrefix csp; char order = 0;
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);
/* try to read the byte-order of the connection */ /* try to read the byte-order of the connection */
(void)_XSERVTransRead(trans_conn, &byteOrder, 1); (void)_XSERVTransRead(trans_conn, &order, 1);
if ((byteOrder == 'l') || (byteOrder == 'B')) 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.success = xFalse;
csp.lengthReason = sizeof(NOROOM) - 1; csp.lengthReason = sizeof(NOROOM) - 1;
csp.length = (sizeof(NOROOM) + 2) >> 2; csp.length = (sizeof(NOROOM) + 2) >> 2;
csp.majorVersion = X_PROTOCOL; csp.majorVersion = X_PROTOCOL;
csp.minorVersion = X_PROTOCOL_REVISION; csp.minorVersion = X_PROTOCOL_REVISION;
if (((*(char *) &whichbyte) && (byteOrder == 'B')) || if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
(!(*(char *) &whichbyte) && (byteOrder == 'l'))) (!(*(char *) &whichbyte) && (order == 'l' || order == 'r')))
{ {
swaps(&csp.majorVersion); swaps(&csp.majorVersion);
swaps(&csp.minorVersion); swaps(&csp.minorVersion);
...@@ -880,6 +945,15 @@ ErrorConnMax(XtransConnInfo trans_conn) ...@@ -880,6 +945,15 @@ ErrorConnMax(XtransConnInfo trans_conn)
iov[2].iov_base = pad; iov[2].iov_base = pad;
(void)_XSERVTransWritev(trans_conn, iov, 3); (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) ...@@ -987,6 +1061,9 @@ CloseDownConnection(ClientPtr client)
{ {
OsCommPtr oc = (OsCommPtr)client->osPrivate; OsCommPtr oc = (OsCommPtr)client->osPrivate;
if (FlushCallback)
CallCallbacks(&FlushCallback, client);
if (oc->output && oc->output->count) if (oc->output && oc->output->count)
FlushClient(client, oc, (char *)NULL, 0); FlushClient(client, oc, (char *)NULL, 0);
#ifdef XDMCP #ifdef XDMCP
......
...@@ -252,7 +252,14 @@ ReadRequestFromClient(ClientPtr client) ...@@ -252,7 +252,14 @@ ReadRequestFromClient(ClientPtr client)
move_header = FALSE; move_header = FALSE;
#endif #endif
gotnow = oci->bufcnt + oci->buffer - oci->bufptr; 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 /* We don't have an entire xReq yet. Can't tell how big
* the request will be until we get the whole xReq. * the request will be until we get the whole xReq.
...@@ -297,8 +304,13 @@ ReadRequestFromClient(ClientPtr client) ...@@ -297,8 +304,13 @@ ReadRequestFromClient(ClientPtr client)
if (needed > MAXBUFSIZE) if (needed > MAXBUFSIZE)
{ {
/* request is too big for us to handle */ /* 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) || if ((gotnow == 0) ||
((oci->bufptr - oci->buffer + needed) > oci->size)) ((oci->bufptr - oci->buffer + needed) > oci->size))
...@@ -405,6 +417,29 @@ ReadRequestFromClient(ClientPtr client) ...@@ -405,6 +417,29 @@ ReadRequestFromClient(ClientPtr client)
#endif #endif
needed = sizeof(xReq); 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; oci->lenLastReq = needed;
/* /*
...@@ -430,24 +465,15 @@ ReadRequestFromClient(ClientPtr client) ...@@ -430,24 +465,15 @@ ReadRequestFromClient(ClientPtr client)
FD_SET(fd, &ClientsWithInput); FD_SET(fd, &ClientsWithInput);
else else
{ {
if (!SmartScheduleDisable) FD_CLR(fd, &ClientsWithInput);
FD_CLR(fd, &ClientsWithInput);
else
YieldControlNoInput();
} }
} }
else else
{ {
if (!gotnow) if (!gotnow)
AvailableInput = oc; AvailableInput = oc;
if (!SmartScheduleDisable) FD_CLR(fd, &ClientsWithInput);
FD_CLR(fd, &ClientsWithInput);
else
YieldControlNoInput();
} }
if (SmartScheduleDisable)
if (++timesThisConnection >= MAX_TIMES_PER)
YieldControl();
#ifdef BIGREQS #ifdef BIGREQS
if (move_header) if (move_header)
{ {
...@@ -755,9 +781,6 @@ FlushAllOutput(void) ...@@ -755,9 +781,6 @@ FlushAllOutput(void)
fd_set newOutputPending; fd_set newOutputPending;
#endif #endif
if (FlushCallback)
CallCallbacks(&FlushCallback, NULL);
if (!newoutput) if (!newoutput)
return; return;
...@@ -958,7 +981,7 @@ WriteToClient (ClientPtr who, int count, const void *__buf) ...@@ -958,7 +981,7 @@ WriteToClient (ClientPtr who, int count, const void *__buf)
} }
} }
#endif #endif
if (oco->count + count + padBytes > oco->size) if (oco->count == 0 || oco->count + count + padBytes > oco->size)
{ {
FD_CLR(oc->fd, &OutputPending); FD_CLR(oc->fd, &OutputPending);
if(!XFD_ANYSET(&OutputPending)) { if(!XFD_ANYSET(&OutputPending)) {
...@@ -971,7 +994,11 @@ WriteToClient (ClientPtr who, int count, const void *__buf) ...@@ -971,7 +994,11 @@ WriteToClient (ClientPtr who, int count, const void *__buf)
NewOutputPending = TRUE; NewOutputPending = TRUE;
FD_SET(oc->fd, &OutputPending); FD_SET(oc->fd, &OutputPending);
memmove((char *)oco->buf + oco->count, buf, count); 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); return(count);
} }
...@@ -1004,6 +1031,13 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) ...@@ -1004,6 +1031,13 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
written = 0; written = 0;
padsize = padlength[extraCount & 3]; padsize = padlength[extraCount & 3];
notWritten = oco->count + extraCount + padsize; notWritten = oco->count + extraCount + padsize;
if (!notWritten)
return 0;
if (FlushCallback)
CallCallbacks(&FlushCallback, who);
todo = notWritten; todo = notWritten;
while (notWritten) { while (notWritten) {
long before = written; /* amount of whole thing written */ long before = written; /* amount of whole thing written */
...@@ -1083,10 +1117,11 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) ...@@ -1083,10 +1117,11 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
if (notWritten > oco->size) if (notWritten > oco->size)
{ {
unsigned char *obuf; unsigned char *obuf = NULL;
obuf = (unsigned char *)realloc(oco->buf, if (notWritten + BUFSIZE <= INT_MAX) {
notWritten + BUFSIZE); obuf = realloc(oco->buf, notWritten + BUFSIZE);
}
if (!obuf) if (!obuf)
{ {
_XSERVTransDisconnect(oc->trans_conn); _XSERVTransDisconnect(oc->trans_conn);
...@@ -1173,6 +1208,7 @@ AllocateInputBuffer(void) ...@@ -1173,6 +1208,7 @@ AllocateInputBuffer(void)
oci->bufptr = oci->buffer; oci->bufptr = oci->buffer;
oci->bufcnt = 0; oci->bufcnt = 0;
oci->lenLastReq = 0; oci->lenLastReq = 0;
oci->ignoreBytes = 0;
return oci; return oci;
} }
...@@ -1217,6 +1253,7 @@ FreeOsBuffers(OsCommPtr oc) ...@@ -1217,6 +1253,7 @@ FreeOsBuffers(OsCommPtr oc)
oci->bufptr = oci->buffer; oci->bufptr = oci->buffer;
oci->bufcnt = 0; oci->bufcnt = 0;
oci->lenLastReq = 0; oci->lenLastReq = 0;
oci->ignoreBytes = 0;
} }
} }
if ((oco = oc->output)) if ((oco = oc->output))
......
...@@ -179,48 +179,87 @@ static Bool needBuffer = TRUE; ...@@ -179,48 +179,87 @@ static Bool needBuffer = TRUE;
#endif #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 * 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 * 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. * 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 * %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 * const char *
LogInit(const char *fname, const char *backup) LogInit(const char *fname, const char *backup)
{ {
char *logFileName = NULL; char *logFileName = NULL;
if (fname && *fname) { if (fname && *fname) {
/* malloc() can't be used yet. */ if (displayfd != -1) {
logFileName = malloc(strlen(fname) + strlen(display) + 1); /* Display isn't set yet, so we can't use it in filenames yet. */
if (!logFileName) char pidstring[32];
FatalError("Cannot allocate space for the log file name\n"); snprintf(pidstring, sizeof(pidstring), "pid-%ld",
sprintf(logFileName, fname, display); (unsigned long) getpid());
logFileName = LogFilePrep(fname, backup, pidstring);
if (backup && *backup) { saved_log_tempname = logFileName;
struct stat buf;
/* Save the patterns for use when the display is named. */
if (!stat(logFileName, &buf) && S_ISREG(buf.st_mode)) { saved_log_fname = strdup(fname);
char *suffix; if (backup == NULL)
char *oldLog; saved_log_backup = NULL;
else
oldLog = malloc(strlen(logFileName) + strlen(backup) + saved_log_backup = strdup(backup);
strlen(display) + 1); } else
suffix = malloc(strlen(backup) + strlen(display) + 1); logFileName = LogFilePrep(fname, backup, display);
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 ((logFile = fopen(logFileName, "w")) == NULL) if ((logFile = fopen(logFileName, "w")) == NULL)
FatalError("Cannot open log file \"%s\"\n", logFileName); FatalError("Cannot open log file \"%s\"\n", logFileName);
setvbuf(logFile, NULL, _IONBF, 0); setvbuf(logFile, NULL, _IONBF, 0);
...@@ -250,6 +289,36 @@ LogInit(const char *fname, const char *backup) ...@@ -250,6 +289,36 @@ LogInit(const char *fname, const char *backup)
} }
void 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() LogClose()
{ {
if (logFile) { if (logFile) {
......
...@@ -52,7 +52,6 @@ SOFTWARE. ...@@ -52,7 +52,6 @@ SOFTWARE.
#ifndef _OSDEP_H_ #ifndef _OSDEP_H_
#define _OSDEP_H_ 1 #define _OSDEP_H_ 1
#define BOTIMEOUT 200 /* in milliseconds */
#define BUFSIZE 4096 #define BUFSIZE 4096
#define BUFWATERMARK 8192 #define BUFWATERMARK 8192
#ifndef MAXBUFSIZE #ifndef MAXBUFSIZE
...@@ -129,6 +128,7 @@ typedef struct _connectionInput { ...@@ -129,6 +128,7 @@ typedef struct _connectionInput {
int bufcnt; /* count of bytes in buffer */ int bufcnt; /* count of bytes in buffer */
int lenLastReq; int lenLastReq;
int size; int size;
unsigned int ignoreBytes; /* bytes to ignore before the next request */
} ConnectionInput, *ConnectionInputPtr; } ConnectionInput, *ConnectionInputPtr;
typedef struct _connectionOutput { typedef struct _connectionOutput {
...@@ -238,6 +238,9 @@ typedef long int fd_mask; ...@@ -238,6 +238,9 @@ typedef long int fd_mask;
#define ffs mffs #define ffs mffs
extern int mffs(fd_mask); extern int mffs(fd_mask);
/* in access.c */
extern Bool ComputeLocalClient(ClientPtr client);
/* in auth.c */ /* in auth.c */
extern void GenerateRandomData (int len, char *buf); extern void GenerateRandomData (int len, char *buf);
......
...@@ -217,9 +217,8 @@ OsInit(void) ...@@ -217,9 +217,8 @@ OsInit(void)
* log file name if logging to a file is desired. * log file name if logging to a file is desired.
*/ */
LogInit(NULL, NULL); LogInit(NULL, NULL);
if (!SmartScheduleDisable) SmartScheduleInit();
if (!SmartScheduleInit ())
SmartScheduleDisable = TRUE;
OsInitAllocator(); OsInitAllocator();
} }
......
...@@ -290,7 +290,8 @@ OsSignal(sig, handler) ...@@ -290,7 +290,8 @@ OsSignal(sig, handler)
sigaddset(&act.sa_mask, sig); sigaddset(&act.sa_mask, sig);
act.sa_flags = 0; act.sa_flags = 0;
act.sa_handler = handler; act.sa_handler = handler;
sigaction(sig, &act, &oact); if (sigaction(sig, &act, &oact))
perror("sigaction");
return oact.sa_handler; return oact.sa_handler;
#endif #endif
} }
...@@ -337,7 +338,7 @@ LockServer(void) ...@@ -337,7 +338,7 @@ LockServer(void)
int len; int len;
char port[20]; char port[20];
if (nolock) return; if (nolock || NoListenAll) return;
/* /*
* Path names * Path names
*/ */
...@@ -463,7 +464,7 @@ LockServer(void) ...@@ -463,7 +464,7 @@ LockServer(void)
void void
UnlockServer(void) UnlockServer(void)
{ {
if (nolock) return; if (nolock || NoListenAll) return;
if (!StillLocking){ if (!StillLocking){
...@@ -621,7 +622,6 @@ void UseMsg(void) ...@@ -621,7 +622,6 @@ void UseMsg(void)
ErrorF("v video blanking for screen-saver\n"); ErrorF("v video blanking for screen-saver\n");
ErrorF("-v screen-saver without video blanking\n"); ErrorF("-v screen-saver without video blanking\n");
ErrorF("-wm WhenMapped default backing-store\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"); ErrorF("-maxbigreqsize set maximal bigrequest size \n");
#ifdef PANORAMIX #ifdef PANORAMIX
ErrorF("+xinerama Enable XINERAMA (PanoramiX) extension\n"); ErrorF("+xinerama Enable XINERAMA (PanoramiX) extension\n");
...@@ -703,6 +703,7 @@ ProcessCommandLine(int argc, char *argv[]) ...@@ -703,6 +703,7 @@ ProcessCommandLine(int argc, char *argv[])
{ {
/* initialize display */ /* initialize display */
display = argv[i]; display = argv[i];
explicit_display = TRUE;
display++; display++;
if( ! VerifyDisplayName( display ) ) { if( ! VerifyDisplayName( display ) ) {
ErrorF("Bad display name: %s\n", display); ErrorF("Bad display name: %s\n", display);
...@@ -779,6 +780,15 @@ ProcessCommandLine(int argc, char *argv[]) ...@@ -779,6 +780,15 @@ ProcessCommandLine(int argc, char *argv[])
else else
UseMsg(); UseMsg();
} }
else if (strcmp(argv[i], "-displayfd") == 0) {
if (++i < argc) {
displayfd = atoi(argv[i]);
nolock = TRUE;
}
else
UseMsg();
}
#ifdef DPMSExtension #ifdef DPMSExtension
else if ( strcmp( argv[i], "dpms") == 0) else if ( strcmp( argv[i], "dpms") == 0)
DPMSEnabledSwitch = TRUE; DPMSEnabledSwitch = TRUE;
...@@ -891,6 +901,11 @@ ProcessCommandLine(int argc, char *argv[]) ...@@ -891,6 +901,11 @@ ProcessCommandLine(int argc, char *argv[])
else if ( strcmp( argv[i], "-nolisten") == 0) else if ( strcmp( argv[i], "-nolisten") == 0)
{ {
if(++i < argc) { if(++i < argc) {
#ifdef NXAGENT_SERVER
if (strcmp( argv[i], "ANY" ) == 0)
NoListenAll = TRUE;
else
#endif /* NXAGENT_SERVER */
if (_XSERVTransNoListen(argv[i])) if (_XSERVTransNoListen(argv[i]))
FatalError ("Failed to disable listen for %s transport", FatalError ("Failed to disable listen for %s transport",
argv[i]); argv[i]);
...@@ -996,14 +1011,6 @@ ProcessCommandLine(int argc, char *argv[]) ...@@ -996,14 +1011,6 @@ ProcessCommandLine(int argc, char *argv[])
noRRXineramaExtension = TRUE; noRRXineramaExtension = TRUE;
} }
#endif #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) else if ( strcmp( argv[i], "-I") == 0)
{ {
/* ignore all remaining arguments */ /* ignore all remaining arguments */
...@@ -1026,10 +1033,12 @@ ProcessCommandLine(int argc, char *argv[]) ...@@ -1026,10 +1033,12 @@ ProcessCommandLine(int argc, char *argv[])
i = skip - 1; i = skip - 1;
} }
#endif #endif
#if HAVE_SETITIMER
else if ( strcmp( argv[i], "-dumbSched") == 0) else if ( strcmp( argv[i], "-dumbSched") == 0)
{ {
SmartScheduleDisable = TRUE; SmartScheduleSignalEnable = FALSE;
} }
#endif
else if ( strcmp( argv[i], "-schedInterval") == 0) else if ( strcmp( argv[i], "-schedInterval") == 0)
{ {
if (++i < argc) if (++i < argc)
...@@ -1353,30 +1362,15 @@ XNFstrdup(const char *s) ...@@ -1353,30 +1362,15 @@ XNFstrdup(const char *s)
return ret; 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 void
SmartScheduleStopTimer (void) SmartScheduleStopTimer (void)
#else
static void
SmartScheduleStopTimer (void)
#endif
{ {
#ifdef SMART_SCHEDULE_POSSIBLE #if HAVE_SETITIMER
struct itimerval timer; struct itimerval timer;
if (!SmartScheduleSignalEnable)
return;
#ifdef NX_TRANS_TEST #ifdef NX_TRANS_TEST
fprintf(stderr, "SmartScheduleStopTimer: Stopping timer.\n"); fprintf(stderr, "SmartScheduleStopTimer: Stopping timer.\n");
#endif #endif
...@@ -1386,96 +1380,101 @@ SmartScheduleStopTimer (void) ...@@ -1386,96 +1380,101 @@ SmartScheduleStopTimer (void)
timer.it_value.tv_sec = 0; timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 0; timer.it_value.tv_usec = 0;
(void) setitimer (ITIMER_REAL, &timer, 0); (void) setitimer (ITIMER_REAL, &timer, 0);
SmartScheduleTimerStopped = TRUE;
#endif #endif
} }
Bool void
SmartScheduleStartTimer (void) SmartScheduleStartTimer (void)
{ {
#ifdef SMART_SCHEDULE_POSSIBLE #if HAVE_SETITIMER
struct itimerval timer; struct itimerval timer;
#ifdef NX_TRANS_SOCKET if (!SmartScheduleSignalEnable)
return;
if (SmartScheduleDisable)
{
return FALSE;
}
#endif
#ifdef NX_TRANS_TEST #ifdef NX_TRANS_TEST
fprintf(stderr, "SmartScheduleStartTimer: Starting timer with [%ld] ms.\n", fprintf(stderr, "SmartScheduleStartTimer: Starting timer with [%ld] ms.\n",
SmartScheduleInterval); SmartScheduleInterval);
#endif #endif
SmartScheduleTimerStopped = FALSE;
timer.it_interval.tv_sec = 0; timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = SmartScheduleInterval * 1000; timer.it_interval.tv_usec = SmartScheduleInterval * 1000;
timer.it_value.tv_sec = 0; timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = SmartScheduleInterval * 1000; timer.it_value.tv_usec = SmartScheduleInterval * 1000;
return setitimer (ITIMER_REAL, &timer, 0) >= 0; setitimer (ITIMER_REAL, &timer, 0);
#endif #endif
return FALSE;
} }
#ifdef SMART_SCHEDULE_POSSIBLE #if HAVE_SETITIMER
static void static void
SmartScheduleTimer (int sig) SmartScheduleTimer (int sig)
{ {
int olderrno = errno;
SmartScheduleTime += SmartScheduleInterval; SmartScheduleTime += SmartScheduleInterval;
#ifdef NX_TRANS_TEST #ifdef NX_TRANS_TEST
fprintf(stderr, "SmartScheduleTimer: Got timer with time [%ld] ms.\n", fprintf(stderr, "SmartScheduleTimer: Got timer with time [%ld] ms.\n",
SmartScheduleTime); SmartScheduleTime);
#endif #endif
if (SmartScheduleIdle)
{
SmartScheduleStopTimer ();
}
errno = olderrno;
} }
#endif
Bool int
SmartScheduleInit (void) SmartScheduleEnable (void)
{ {
#ifdef SMART_SCHEDULE_POSSIBLE int ret = 0;
struct sigaction act; struct sigaction act;
if (SmartScheduleDisable) if (!SmartScheduleSignalEnable)
return TRUE; return 0;
#ifdef NX_TRANS_TEST #ifdef NX_TRANS_TEST
fprintf(stderr, "SmartScheduleInit: Initializing the smart scheduler.\n"); fprintf(stderr, "SmartScheduleEnable: Enabling the smart scheduler.\n");
#endif #endif
bzero ((char *) &act, sizeof(struct sigaction)); memset((char *) &act, 0, sizeof(struct sigaction));
/* Set up the timer signal function */ /* Set up the timer signal function */
act.sa_flags = SA_RESTART;
act.sa_handler = SmartScheduleTimer; act.sa_handler = SmartScheduleTimer;
sigemptyset (&act.sa_mask); sigemptyset (&act.sa_mask);
sigaddset (&act.sa_mask, SMART_SCHEDULE_SIGNAL); sigaddset (&act.sa_mask, SIGALRM);
if (sigaction (SMART_SCHEDULE_SIGNAL, &act, 0) < 0) ret = sigaction(SIGALRM, &act, 0);
{ return ret;
perror ("sigaction for smart scheduler"); }
return FALSE;
} static int
/* Set up the virtual timer */ SmartSchedulePause(void)
if (!SmartScheduleStartTimer ()) {
{ int ret = 0;
perror ("scheduling timer"); struct sigaction act;
return FALSE;
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 #endif
} }
...@@ -1558,7 +1557,11 @@ System(char *command) ...@@ -1558,7 +1557,11 @@ System(char *command)
return(1); return(1);
#ifdef SIGCHLD #ifdef SIGCHLD
csig = signal(SIGCHLD, SIG_DFL); csig = OsSignal(SIGCHLD, SIG_DFL);
if (csig == SIG_ERR) {
perror("signal");
return -1;
}
#endif #endif
#ifdef DEBUG #ifdef DEBUG
...@@ -1596,7 +1599,10 @@ System(char *command) ...@@ -1596,7 +1599,10 @@ System(char *command)
#endif #endif
#ifdef SIGCHLD #ifdef SIGCHLD
signal(SIGCHLD, csig); if (OsSignal(SIGCHLD, csig) == SIG_ERR) {
perror("signal");
return -1;
}
#endif #endif
return p == -1 ? -1 : status; return p == -1 ? -1 : status;
...@@ -1629,6 +1635,17 @@ Popen(char *command, char *type) ...@@ -1629,6 +1635,17 @@ Popen(char *command, char *type)
return NULL; 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 #ifdef NX_TRANS_EXIT
if (OsVendorStartRedirectErrorFProc != NULL) { if (OsVendorStartRedirectErrorFProc != NULL) {
OsVendorStartRedirectErrorFProc(); OsVendorStartRedirectErrorFProc();
...@@ -1640,6 +1657,10 @@ Popen(char *command, char *type) ...@@ -1640,6 +1657,10 @@ Popen(char *command, char *type)
close(pdes[0]); close(pdes[0]);
close(pdes[1]); close(pdes[1]);
free(cur); free(cur);
#if HAVE_SETITIMER
if (SmartScheduleEnable() < 0)
perror("signal");
#endif
#ifdef NX_TRANS_EXIT #ifdef NX_TRANS_EXIT
if (OsVendorEndRedirectErrorFProc != NULL) { if (OsVendorEndRedirectErrorFProc != NULL) {
OsVendorEndRedirectErrorFProc(); OsVendorEndRedirectErrorFProc();
...@@ -1714,6 +1735,13 @@ Popen(char *command, char *type) ...@@ -1714,6 +1735,13 @@ Popen(char *command, char *type)
OsReleaseSignals (); OsReleaseSignals ();
#endif #endif
#if HAVE_SETITIMER
if (SmartScheduleEnable() < 0) {
perror("signal");
return NULL;
}
#endif
execl("/bin/sh", "sh", "-c", command, (char *)NULL); execl("/bin/sh", "sh", "-c", command, (char *)NULL);
_exit(127); _exit(127);
} }
......
...@@ -205,8 +205,6 @@ extern void XdmcpDeadSession(char * /*reason*/); ...@@ -205,8 +205,6 @@ extern void XdmcpDeadSession(char * /*reason*/);
static void timeout(void); static void timeout(void);
static void restart(void);
static void XdmcpBlockHandler( static void XdmcpBlockHandler(
void * /*data*/, void * /*data*/,
struct timeval ** /*wt*/, struct timeval ** /*wt*/,
...@@ -959,14 +957,6 @@ timeout(void) ...@@ -959,14 +957,6 @@ timeout(void)
send_packet(); send_packet();
} }
static void
restart(void)
{
state = XDM_INIT_STATE;
timeOutRtx = 0;
send_packet();
}
int int
XdmcpCheckAuthentication ( XdmcpCheckAuthentication (
ARRAY8Ptr Name, ARRAY8Ptr Name,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment