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