summaryrefslogtreecommitdiff
path: root/xserver/os
diff options
context:
space:
mode:
Diffstat (limited to 'xserver/os')
-rw-r--r--xserver/os/Makefile.in16
-rw-r--r--xserver/os/WaitFor.c2
-rw-r--r--xserver/os/access.c12
-rw-r--r--xserver/os/backtrace.c49
-rw-r--r--xserver/os/connection.c91
-rw-r--r--xserver/os/io.c34
-rw-r--r--xserver/os/log.c238
-rw-r--r--xserver/os/osdep.h19
-rw-r--r--xserver/os/osinit.c62
-rw-r--r--xserver/os/strndup.c4
-rw-r--r--xserver/os/utils.c293
-rw-r--r--xserver/os/xdmcp.c14
-rw-r--r--xserver/os/xsha1.c72
13 files changed, 751 insertions, 155 deletions
diff --git a/xserver/os/Makefile.in b/xserver/os/Makefile.in
index 572083293..a4abaaa3f 100644
--- a/xserver/os/Makefile.in
+++ b/xserver/os/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.12.3 from Makefile.am.
+# Makefile.in generated by automake 1.12.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2012 Free Software Foundation, Inc.
@@ -207,13 +207,9 @@ DMXXMUEXAMPLES_DEP_LIBS = @DMXXMUEXAMPLES_DEP_LIBS@
DOXYGEN = @DOXYGEN@
DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@
DRI2PROTO_LIBS = @DRI2PROTO_LIBS@
-DRIPROTO_CFLAGS = @DRIPROTO_CFLAGS@
-DRIPROTO_LIBS = @DRIPROTO_LIBS@
DRIVER_MAN_DIR = @DRIVER_MAN_DIR@
DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@
-DRI_CFLAGS = @DRI_CFLAGS@
DRI_DRIVER_PATH = @DRI_DRIVER_PATH@
-DRI_LIBS = @DRI_LIBS@
DSYMUTIL = @DSYMUTIL@
DTRACE = @DTRACE@
DUMPBIN = @DUMPBIN@
@@ -235,6 +231,7 @@ FONTTYPE1DIR = @FONTTYPE1DIR@
FOP = @FOP@
GLX_ARCH_DEFINES = @GLX_ARCH_DEFINES@
GLX_DEFINES = @GLX_DEFINES@
+GLX_SYS_LIBS = @GLX_SYS_LIBS@
GLX_TLS = @GLX_TLS@
GL_CFLAGS = @GL_CFLAGS@
GL_LIBS = @GL_LIBS@
@@ -259,6 +256,7 @@ KHRONOS_SPEC_DIR = @KHRONOS_SPEC_DIR@
LD = @LD@
LDFLAGS = @LDFLAGS@
LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@
+LD_NO_UNDEFINED_FLAG = @LD_NO_UNDEFINED_FLAG@
LEX = @LEX@
LEXLIB = @LEXLIB@
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
@@ -274,7 +272,6 @@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
MAIN_LIB = @MAIN_LIB@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -373,6 +370,7 @@ XNESTMODULES_LIBS = @XNESTMODULES_LIBS@
XNEST_LIBS = @XNEST_LIBS@
XNEST_SYS_LIBS = @XNEST_SYS_LIBS@
XORG_CFLAGS = @XORG_CFLAGS@
+XORG_DRIVER_LIBS = @XORG_DRIVER_LIBS@
XORG_INCS = @XORG_INCS@
XORG_LIBS = @XORG_LIBS@
XORG_MALLOC_DEBUG_ENV = @XORG_MALLOC_DEBUG_ENV@
@@ -489,7 +487,7 @@ all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
@@ -514,9 +512,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
diff --git a/xserver/os/WaitFor.c b/xserver/os/WaitFor.c
index 59f3af649..393890f19 100644
--- a/xserver/os/WaitFor.c
+++ b/xserver/os/WaitFor.c
@@ -561,7 +561,7 @@ NextDPMSTimeout(INT32 timeout)
static CARD32
ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg)
{
- INT32 timeout = now - lastDeviceEventTime.milliseconds;
+ INT32 timeout = now - lastDeviceEventTime[XIAllDevices].milliseconds;
CARD32 nextTimeout = 0;
#ifdef DPMSExtension
diff --git a/xserver/os/access.c b/xserver/os/access.c
index 550f2ed8c..88a44d9e5 100644
--- a/xserver/os/access.c
+++ b/xserver/os/access.c
@@ -471,7 +471,7 @@ in6_fillscopeid(struct sockaddr_in6 *sin6)
#if defined(__KAME__)
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
sin6->sin6_scope_id =
- ntohs(*(u_int16_t *) & sin6->sin6_addr.s6_addr[2]);
+ ntohs(*(u_int16_t *) &sin6->sin6_addr.s6_addr[2]);
sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
}
#endif
@@ -1007,14 +1007,6 @@ ComputeLocalClient(ClientPtr client)
return FALSE;
}
-Bool
-LocalClient(ClientPtr client)
-{
- if (!client->osPrivate)
- return FALSE;
- return ((OsCommPtr) client->osPrivate)->local_client;
-}
-
/*
* Return the uid and gid of a connected local client
*
@@ -1176,7 +1168,7 @@ AuthorizedClient(ClientPtr client)
if (rc != Success)
return rc;
- return LocalClient(client) ? Success : BadAccess;
+ return client->local ? Success : BadAccess;
}
/* Add a host to the access control list. This is the external interface
diff --git a/xserver/os/backtrace.c b/xserver/os/backtrace.c
index 81348f417..daac60cf6 100644
--- a/xserver/os/backtrace.c
+++ b/xserver/os/backtrace.c
@@ -45,29 +45,37 @@ xorg_backtrace(void)
int size, i;
Dl_info info;
- ErrorF("\n");
- ErrorF("Backtrace:\n");
+ ErrorFSigSafe("\n");
+ ErrorFSigSafe("Backtrace:\n");
size = backtrace(array, 64);
for (i = 0; i < size; i++) {
int rc = dladdr(array[i], &info);
if (rc == 0) {
- ErrorF("%d: ?? [%p]\n", i, array[i]);
+ ErrorFSigSafe("%u: ?? [%p]\n", i, array[i]);
continue;
}
mod = (info.dli_fname && *info.dli_fname) ? info.dli_fname : "(vdso)";
if (info.dli_saddr)
- ErrorF("%d: %s (%s+0x%lx) [%p]\n", i, mod,
- info.dli_sname,
- (long unsigned int) ((char *) array[i] -
- (char *) info.dli_saddr), array[i]);
+ ErrorFSigSafe(
+ "%u: %s (%s+0x%x) [%p]\n",
+ i,
+ mod,
+ info.dli_sname,
+ (unsigned int)((char *) array[i] -
+ (char *) info.dli_saddr),
+ array[i]);
else
- ErrorF("%d: %s (%p+0x%lx) [%p]\n", i, mod,
- info.dli_fbase,
- (long unsigned int) ((char *) array[i] -
- (char *) info.dli_fbase), array[i]);
+ ErrorFSigSafe(
+ "%u: %s (%p+0x%x) [%p]\n",
+ i,
+ mod,
+ info.dli_fbase,
+ (unsigned int)((char *) array[i] -
+ (char *) info.dli_fbase),
+ array[i]);
}
- ErrorF("\n");
+ ErrorFSigSafe("\n");
}
#else /* not glibc or glibc < 2.1 */
@@ -105,7 +113,7 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
strcpy(signame, "unknown");
}
- ErrorF("** Signal %d (%s)\n", signo, signame);
+ ErrorFSigSafe("** Signal %u (%s)\n", signo, signame);
}
snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc);
@@ -123,7 +131,8 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
symname = "<section start>";
offset = pc - (uintptr_t) dlinfo.dli_fbase;
}
- ErrorF("%s: %s:%s+0x%lx\n", header, dlinfo.dli_fname, symname, offset);
+ ErrorFSigSafe("%s: %s:%s+0x%x\n", header, dlinfo.dli_fname, symname,
+ offset);
}
else {
@@ -131,7 +140,7 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
* probably poke elfloader here, but haven't written that code yet,
* so we just print the pc.
*/
- ErrorF("%s\n", header);
+ ErrorFSigSafe("%s\n", header);
}
return 0;
@@ -183,7 +192,7 @@ xorg_backtrace_pstack(void)
if (bytesread > 0) {
btline[bytesread] = 0;
- ErrorF("%s", btline);
+ ErrorFSigSafe("%s", btline);
}
else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN)))
done = 1;
@@ -203,8 +212,8 @@ void
xorg_backtrace(void)
{
- ErrorF("\n");
- ErrorF("Backtrace:\n");
+ ErrorFSigSafe("\n");
+ ErrorFSigSafe("Backtrace:\n");
#ifdef HAVE_PSTACK
/* First try fork/exec of pstack - otherwise fall back to walkcontext
@@ -221,9 +230,9 @@ xorg_backtrace(void)
walkcontext(&u, xorg_backtrace_frame, &depth);
else
#endif
- ErrorF("Failed to get backtrace info: %s\n", strerror(errno));
+ ErrorFSigSafe("Failed to get backtrace info: %s\n", strerror(errno));
}
- ErrorF("\n");
+ ErrorFSigSafe("\n");
}
#else
diff --git a/xserver/os/connection.c b/xserver/os/connection.c
index f5a94a750..9d95686c7 100644
--- a/xserver/os/connection.c
+++ b/xserver/os/connection.c
@@ -142,6 +142,7 @@ Bool AnyClientsWriteBlocked; /* true if some client blocked on write */
static Bool RunFromSmartParent; /* send SIGUSR1 to parent process */
Bool RunFromSigStopParent; /* send SIGSTOP to our own process; Upstart (or
equivalent) will send SIGCONT back. */
+static char dynamic_display[7]; /* display name */
Bool PartialNetwork; /* continue even if unable to bind all addrs */
static Pid_t ParentProcess;
@@ -353,20 +354,37 @@ void
NotifyParentProcess(void)
{
#if !defined(WIN32)
+ if (dynamic_display[0]) {
+ write(displayfd, dynamic_display, strlen(dynamic_display));
+ write(displayfd, "\n", 1);
+ close(displayfd);
+ }
if (RunFromSmartParent) {
- if (ParentProcess > 1) {
+ if (ParentProcess > 1) {
#ifdef X_PRIVSEP
priv_signal_parent();
#else
kill (ParentProcess, SIGUSR1);
#endif
- }
+ }
}
if (RunFromSigStopParent)
raise(SIGSTOP);
#endif
}
+static Bool
+TryCreateSocket(int num, int *partial)
+{
+ char port[20];
+
+ snprintf(port, sizeof(port), "%d", num);
+
+ return (_XSERVTransMakeAllCOTSServerListeners(port, partial,
+ &ListenTransCount,
+ &ListenTransConns) >= 0);
+}
+
/*****************
* CreateWellKnownSockets
* At initialization, create the sockets to listen on for new clients.
@@ -377,7 +395,6 @@ CreateWellKnownSockets(void)
{
int i;
int partial;
- char port[20];
FD_ZERO(&AllSockets);
FD_ZERO(&AllClients);
@@ -393,29 +410,41 @@ CreateWellKnownSockets(void)
FD_ZERO(&WellKnownConnections);
- snprintf(port, sizeof(port), "%d", atoi(display));
-
- if ((_XSERVTransMakeAllCOTSServerListeners(port, &partial,
- &ListenTransCount,
- &ListenTransConns) >= 0) &&
- (ListenTransCount >= 1)) {
- if (!PartialNetwork && partial) {
- FatalError("Failed to establish all listening sockets");
+ /* display is initialized to "0" by main(). It is then set to the display
+ * number if specified on the command line, or to NULL when the -displayfd
+ * option is used. */
+ if (display) {
+ if (TryCreateSocket(atoi(display), &partial) &&
+ ListenTransCount >= 1)
+ if (!PartialNetwork && partial)
+ FatalError ("Failed to establish all listening sockets");
+ }
+ else { /* -displayfd */
+ Bool found = 0;
+ for (i = 0; i < 65535 - X_TCP_PORT; i++) {
+ if (TryCreateSocket(i, &partial) && !partial) {
+ found = 1;
+ break;
+ }
+ else
+ CloseWellKnownConnections();
}
- else {
- ListenTransFds = malloc(ListenTransCount * sizeof(int));
+ if (!found)
+ FatalError("Failed to find a socket to listen on");
+ snprintf(dynamic_display, sizeof(dynamic_display), "%d", i);
+ display = dynamic_display;
+ }
- for (i = 0; i < ListenTransCount; i++) {
- int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
+ ListenTransFds = malloc(ListenTransCount * sizeof (int));
- ListenTransFds[i] = fd;
- FD_SET(fd, &WellKnownConnections);
+ for (i = 0; i < ListenTransCount; i++) {
+ int fd = _XSERVTransGetConnectionNumber(ListenTransConns[i]);
- if (!_XSERVTransIsLocal(ListenTransConns[i])) {
- DefineSelf(fd);
- }
- }
- }
+ ListenTransFds[i] = fd;
+ FD_SET(fd, &WellKnownConnections);
+
+ if (!_XSERVTransIsLocal(ListenTransConns[i]))
+ DefineSelf (fd);
}
if (!XFD_ANYSET(&WellKnownConnections))
@@ -742,7 +771,7 @@ AllocNewConnection(XtransConnInfo trans_conn, int fd, CARD32 conn_time)
free(oc);
return NullClient;
}
- oc->local_client = ComputeLocalClient(client);
+ client->local = ComputeLocalClient(client);
#if !defined(WIN32)
ConnectionTranslation[fd] = client->index;
#else
@@ -870,9 +899,9 @@ ErrorConnMax(XtransConnInfo trans_conn)
{
int fd = _XSERVTransGetConnectionNumber(trans_conn);
xConnSetupPrefix csp;
- char pad[3];
+ char pad[3] = { 0, 0, 0 };
struct iovec iov[3];
- char byteOrder = 0;
+ char order = 0;
int whichbyte = 1;
struct timeval waittime;
fd_set mask;
@@ -885,15 +914,15 @@ ErrorConnMax(XtransConnInfo trans_conn)
FD_SET(fd, &mask);
(void) Select(fd + 1, &mask, NULL, NULL, &waittime);
/* try to read the byte-order of the connection */
- (void) _XSERVTransRead(trans_conn, &byteOrder, 1);
- if ((byteOrder == 'l') || (byteOrder == 'B')) {
+ (void) _XSERVTransRead(trans_conn, &order, 1);
+ if (order == 'l' || order == 'B' || order == 'r' || order == 'R') {
csp.success = xFalse;
csp.lengthReason = sizeof(NOROOM) - 1;
csp.length = (sizeof(NOROOM) + 2) >> 2;
csp.majorVersion = X_PROTOCOL;
csp.minorVersion = X_PROTOCOL_REVISION;
- if (((*(char *) &whichbyte) && (byteOrder == 'B')) ||
- (!(*(char *) &whichbyte) && (byteOrder == 'l'))) {
+ if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
+ (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) {
swaps(&csp.majorVersion);
swaps(&csp.minorVersion);
swaps(&csp.length);
@@ -1016,8 +1045,8 @@ CloseDownConnection(ClientPtr client)
if (FlushCallback)
CallCallbacks(&FlushCallback, NULL);
- if (oc->output && oc->output->count)
- FlushClient(client, oc, (char *) NULL, 0);
+ if (oc->output)
+ FlushClient(client, oc, (char *) NULL, 0);
#ifdef XDMCP
XdmcpCloseDisplay(oc->fd);
#endif
diff --git a/xserver/os/io.c b/xserver/os/io.c
index b67a5f324..2f091c417 100644
--- a/xserver/os/io.c
+++ b/xserver/os/io.c
@@ -82,6 +82,23 @@ SOFTWARE.
CallbackListPtr ReplyCallback;
CallbackListPtr FlushCallback;
+typedef struct _connectionInput {
+ struct _connectionInput *next;
+ char *buffer; /* contains current client input */
+ char *bufptr; /* pointer to current start of data */
+ int bufcnt; /* count of bytes in buffer */
+ int lenLastReq;
+ int size;
+ unsigned int ignoreBytes; /* bytes to ignore before the next request */
+} ConnectionInput;
+
+typedef struct _connectionOutput {
+ struct _connectionOutput *next;
+ unsigned char *buf;
+ int size;
+ int count;
+} ConnectionOutput;
+
static ConnectionInputPtr AllocateInputBuffer(void);
static ConnectionOutputPtr AllocateOutputBuffer(void);
@@ -578,8 +595,6 @@ ResetCurrentRequest(ClientPtr client)
}
}
-static const int padlength[4] = { 0, 3, 2, 1 };
-
/********************
* FlushAllOutput()
* Flush all clients with output. However, if some client still
@@ -757,7 +772,7 @@ WriteToClient(ClientPtr who, int count, const void *__buf)
oc->output = oco;
}
- padBytes = padlength[count & 3];
+ padBytes = padding_for_int32(count);
if (ReplyCallback) {
ReplyInfoRec replyinfo;
@@ -815,7 +830,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;
}
@@ -844,10 +863,13 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
long todo;
if (!oco)
- return 0;
+ return 0;
written = 0;
- padsize = padlength[extraCount & 3];
+ padsize = padding_for_int32(extraCount);
notWritten = oco->count + extraCount + padsize;
+ if (!notWritten)
+ return 0;
+
todo = notWritten;
while (notWritten) {
long before = written; /* amount of whole thing written */
diff --git a/xserver/os/log.c b/xserver/os/log.c
index 0e4957295..95bd8cca9 100644
--- a/xserver/os/log.c
+++ b/xserver/os/log.c
@@ -108,6 +108,7 @@ void (*OsVendorVErrorFProc) (const char *, va_list args) = NULL;
#endif
static FILE *logFile = NULL;
+static int logFileFd = -1;
static Bool logFlush = FALSE;
static Bool logSync = FALSE;
static int logVerbosity = DEFAULT_LOG_VERBOSITY;
@@ -164,10 +165,21 @@ asm(".desc ___crashreporter_info__, 0x10");
#ifndef X_NOT_IMPLEMENTED_STRING
#define X_NOT_IMPLEMENTED_STRING "(NI)"
#endif
+#ifndef X_DEBUG_STRING
+#define X_DEBUG_STRING "(DB)"
+#endif
#ifndef X_NONE_STRING
#define X_NONE_STRING ""
#endif
+static size_t
+strlen_sigsafe(const char *s)
+{
+ size_t len;
+ for (len = 0; s[len]; len++);
+ return len;
+}
+
/*
* 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
@@ -208,6 +220,8 @@ LogInit(const char *fname, const char *backup)
FatalError("Cannot open log file \"%s\"\n", logFileName);
setvbuf(logFile, NULL, _IONBF, 0);
+ logFileFd = fileno(logFile);
+
/* Flush saved log information. */
if (saveBuffer && bufferSize > 0) {
fwrite(saveBuffer, bufferPos, 1, logFile);
@@ -240,6 +254,7 @@ LogClose(enum ExitCode error)
(error == EXIT_NO_ERROR) ? "successfully" : "with error", error);
fclose(logFile);
logFile = NULL;
+ logFileFd = -1;
}
}
@@ -264,16 +279,125 @@ LogSetParameter(LogParameter param, int value)
}
}
-/* This function does the actual log message writes. */
+static int
+pnprintf(char *string, size_t size, const char *f, va_list args)
+{
+ int f_idx = 0;
+ int s_idx = 0;
+ int f_len = strlen_sigsafe(f);
+ char *string_arg;
+ char number[21];
+ int p_len;
+ int i;
+ uint64_t ui;
+ int64_t si;
+
+ for (; f_idx < f_len && s_idx < size - 1; f_idx++) {
+ if (f[f_idx] != '%') {
+ string[s_idx++] = f[f_idx];
+ continue;
+ }
+
+ f_idx++;
+
+ /* silently swallow length modifiers */
+ while (f_idx < f_len && ((f[f_idx] >= '0' && f[f_idx] <= '9') || f[f_idx] == '.'))
+ f_idx++;
+
+ if (f_idx >= f_len)
+ break;
+
+ switch (f[f_idx]) {
+ case 's':
+ string_arg = va_arg(args, char*);
+ p_len = strlen_sigsafe(string_arg);
+
+ for (i = 0; i < p_len && s_idx < size - 1; i++)
+ string[s_idx++] = string_arg[i];
+ break;
+
+ case 'u':
+ ui = va_arg(args, unsigned);
+ FormatUInt64(ui, number);
+ p_len = strlen_sigsafe(number);
+
+ for (i = 0; i < p_len && s_idx < size - 1; i++)
+ string[s_idx++] = number[i];
+ break;
+ case 'i':
+ case 'd':
+ si = va_arg(args, int);
+ FormatInt64(si, number);
+ p_len = strlen_sigsafe(number);
+
+ for (i = 0; i < p_len && s_idx < size - 1; i++)
+ string[s_idx++] = number[i];
+ break;
+
+ case 'p':
+ string[s_idx++] = '0';
+ if (s_idx < size - 1)
+ string[s_idx++] = 'x';
+ ui = (uintptr_t)va_arg(args, void*);
+ FormatUInt64Hex(ui, number);
+ p_len = strlen_sigsafe(number);
+
+ for (i = 0; i < p_len && s_idx < size - 1; i++)
+ string[s_idx++] = number[i];
+ break;
+
+ case 'x':
+ ui = va_arg(args, unsigned);
+ FormatUInt64Hex(ui, number);
+ p_len = strlen_sigsafe(number);
+
+ for (i = 0; i < p_len && s_idx < size - 1; i++)
+ string[s_idx++] = number[i];
+ break;
+ case 'f':
+ {
+ double d = va_arg(args, double);
+ FormatDouble(d, number);
+ p_len = strlen_sigsafe(number);
+
+ for (i = 0; i < p_len && s_idx < size - 1; i++)
+ string[s_idx++] = number[i];
+ }
+ break;
+ default:
+ va_arg(args, char*);
+ string[s_idx++] = '%';
+ if (s_idx < size - 1)
+ string[s_idx++] = f[f_idx];
+ break;
+ }
+ }
+
+ string[s_idx] = '\0';
+
+ return s_idx;
+}
+
+/* This function does the actual log message writes. It must be signal safe.
+ * When attempting to call non-signal-safe functions, guard them with a check
+ * of the inSignalContext global variable. */
static void
LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
{
static Bool newline = TRUE;
if (verb < 0 || logVerbosity >= verb)
- fwrite(buf, len, 1, stderr);
+ write(2, buf, len);
+
if (verb < 0 || logFileVerbosity >= verb) {
- if (logFile) {
+ if (inSignalContext && logFileFd >= 0) {
+ write(logFileFd, buf, len);
+#ifndef WIN32
+ if (logFlush && logSync)
+ fsync(logFileFd);
+#endif
+ }
+ else if (!inSignalContext && logFile) {
if (newline)
fprintf(logFile, "[%10.3f] ", GetTimeInMillis() / 1000.0);
newline = end_line;
@@ -286,7 +410,7 @@ LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
#endif
}
}
- else if (needBuffer) {
+ else if (!inSignalContext && needBuffer) {
if (len > bufferUnused) {
bufferSize += 1024;
bufferUnused += 1024;
@@ -351,6 +475,8 @@ LogMessageTypeVerbString(MessageType type, int verb)
return X_UNKNOWN_STRING;
case X_NONE:
return X_NONE_STRING;
+ case X_DEBUG:
+ return X_DEBUG_STRING;
default:
return X_UNKNOWN_STRING;
}
@@ -359,12 +485,27 @@ LogMessageTypeVerbString(MessageType type, int verb)
void
LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
{
+ static unsigned int warned;
const char *type_str;
char buf[1024];
const size_t size = sizeof(buf);
Bool newline;
size_t len = 0;
+ if (inSignalContext) {
+ if (warned < 3) {
+ BUG_WARN_MSG(inSignalContext,
+ "Warning: attempting to log data in a signal unsafe "
+ "manner while in signal context.\nPlease update to check "
+ "inSignalContext and/or use LogMessageVerbSigSafe() or "
+ "ErrorFSigSafe().\nThe offending log format message is:\n"
+ "%s\n", format);
+ warned++;
+ if (warned == 3)
+ LogMessageVerbSigSafe(X_WARNING, -1, "Warned %u times about sigsafe logging. Will be quiet now.\n", warned);
+ }
+ }
+
type_str = LogMessageTypeVerbString(type, verb);
if (!type_str)
return;
@@ -406,16 +547,69 @@ LogMessage(MessageType type, const char *format, ...)
va_end(ap);
}
+/* Log a message using only signal safe functions. */
+void
+LogMessageVerbSigSafe(MessageType type, int verb, const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+ LogVMessageVerbSigSafe(type, verb, format, ap);
+ va_end(ap);
+}
+
+void
+LogVMessageVerbSigSafe(MessageType type, int verb, const char *format, va_list args)
+{
+ const char *type_str;
+ char buf[1024];
+ int len;
+ Bool newline;
+
+ type_str = LogMessageTypeVerbString(type, verb);
+ if (!type_str)
+ return;
+
+ /* if type_str is not "", prepend it and ' ', to message */
+ if (type_str[0] != '\0') {
+ LogSWrite(verb, type_str, strlen_sigsafe(type_str), FALSE);
+ LogSWrite(verb, " ", 1, FALSE);
+ }
+
+ len = pnprintf(buf, sizeof(buf), format, args);
+
+ /* Force '\n' at end of truncated line */
+ if (sizeof(buf) - len == 1)
+ buf[len - 1] = '\n';
+
+ newline = (buf[len - 1] == '\n');
+ LogSWrite(verb, buf, len, newline);
+}
+
void
LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
va_list msg_args, const char *hdr_format, va_list hdr_args)
{
+ static unsigned int warned;
const char *type_str;
char buf[1024];
const size_t size = sizeof(buf);
Bool newline;
size_t len = 0;
+ if (inSignalContext) {
+ if (warned < 3) {
+ BUG_WARN_MSG(inSignalContext,
+ "Warning: attempting to log data in a signal unsafe "
+ "manner while in signal context.\nPlease update to check "
+ "inSignalContext and/or use LogMessageVerbSigSafe().\nThe "
+ "offending header and log message formats are:\n%s %s\n",
+ hdr_format, msg_format);
+ warned++;
+ if (warned == 3)
+ LogMessageVerbSigSafe(X_WARNING, -1, "Warned %u times about sigsafe logging. Will be quiet now.\n", warned);
+ }
+ }
+
type_str = LogMessageTypeVerbString(type, verb);
if (!type_str)
return;
@@ -472,7 +666,7 @@ AbortServer(void)
#endif
CloseWellKnownConnections();
OsCleanup(TRUE);
- CloseDownDevices();
+ AbortDevices();
AbortDDX(EXIT_ERR_ABORT);
fflush(stderr);
if (CoreDump)
@@ -583,6 +777,7 @@ void
FatalError(const char *f, ...)
{
va_list args;
+ va_list args2;
static Bool beenhere = FALSE;
if (beenhere)
@@ -591,21 +786,26 @@ FatalError(const char *f, ...)
ErrorF("\nFatal server error:\n");
va_start(args, f);
+
+ /* Make a copy for OsVendorFatalError */
+ va_copy(args2, args);
+
#ifdef __APPLE__
{
- va_list args2;
+ va_list apple_args;
- va_copy(args2, args);
- (void) vsnprintf(__crashreporter_info_buff__,
- sizeof(__crashreporter_info_buff__), f, args2);
- va_end(args2);
+ va_copy(apple_args, args);
+ (void)vsnprintf(__crashreporter_info_buff__,
+ sizeof(__crashreporter_info_buff__), f, apple_args);
+ va_end(apple_args);
}
#endif
VErrorF(f, args);
va_end(args);
ErrorF("\n");
if (!beenhere)
- OsVendorFatalError();
+ OsVendorFatalError(f, args2);
+ va_end(args2);
if (!beenhere) {
beenhere = TRUE;
AbortServer();
@@ -638,6 +838,22 @@ ErrorF(const char *f, ...)
}
void
+VErrorFSigSafe(const char *f, va_list args)
+{
+ LogVMessageVerbSigSafe(X_ERROR, -1, f, args);
+}
+
+void
+ErrorFSigSafe(const char *f, ...)
+{
+ va_list args;
+
+ va_start(args, f);
+ VErrorFSigSafe(f, args);
+ va_end(args);
+}
+
+void
LogPrintMarkers(void)
{
/* Show what the message marker symbols mean. */
diff --git a/xserver/os/osdep.h b/xserver/os/osdep.h
index 2e5a22907..5e979dfc3 100644
--- a/xserver/os/osdep.h
+++ b/xserver/os/osdep.h
@@ -107,22 +107,8 @@ typedef Bool (*AddAuthorFunc) (unsigned name_length, const char *name,
unsigned data_length, char *data);
#endif
-typedef struct _connectionInput {
- struct _connectionInput *next;
- char *buffer; /* contains current client input */
- char *bufptr; /* pointer to current start of data */
- 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 {
- struct _connectionOutput *next;
- int size;
- unsigned char *buf;
- int count;
-} ConnectionOutput, *ConnectionOutputPtr;
+typedef struct _connectionInput *ConnectionInputPtr;
+typedef struct _connectionOutput *ConnectionOutputPtr;
struct _osComm;
@@ -162,7 +148,6 @@ typedef struct _osComm {
XID auth_id; /* authorization id */
CARD32 conn_time; /* timestamp if not established, else 0 */
struct _XtransConnInfo *trans_conn; /* transport connection object */
- Bool local_client;
} OsCommRec, *OsCommPtr;
extern int FlushClient(ClientPtr /*who */ ,
diff --git a/xserver/os/osinit.c b/xserver/os/osinit.c
index 143e872e7..f085671f3 100644
--- a/xserver/os/osinit.c
+++ b/xserver/os/osinit.c
@@ -102,6 +102,7 @@ OsRegisterSigWrapper(OsSigWrapperPtr newSigWrapper)
* OsSigHandler --
* Catch unexpected signals and exit or continue cleanly.
*/
+#if !defined(WIN32) || defined(__CYGWIN__)
static void
#ifdef SA_SIGINFO
OsSigHandler(int signo, siginfo_t * sip, void *unused)
@@ -113,7 +114,7 @@ OsSigHandler(int signo)
const char *dlerr = dlerror();
if (dlerr) {
- LogMessage(X_ERROR, "Dynamic loader error: %s\n", dlerr);
+ LogMessageVerbSigSafe(X_ERROR, 1, "Dynamic loader error: %s\n", dlerr);
}
#endif /* RTLD_DI_SETSIGNAL */
@@ -129,8 +130,8 @@ OsSigHandler(int signo)
#ifdef SA_SIGINFO
if (sip->si_code == SI_USER) {
- ErrorF("Recieved signal %d sent by process %ld, uid %ld\n",
- signo, (long) sip->si_pid, (long) sip->si_uid);
+ ErrorFSigSafe("Received signal %u sent by process %u, uid %u\n", signo,
+ sip->si_pid, sip->si_uid);
}
else {
switch (signo) {
@@ -138,7 +139,7 @@ OsSigHandler(int signo)
case SIGBUS:
case SIGILL:
case SIGFPE:
- ErrorF("%s at address %p\n", strsignal(signo), sip->si_addr);
+ ErrorFSigSafe("%s at address %p\n", strsignal(signo), sip->si_addr);
}
}
#endif
@@ -146,6 +147,7 @@ OsSigHandler(int signo)
FatalError("Caught signal %d (%s). Server aborting\n",
signo, strsignal(signo));
}
+#endif /* !WIN32 || __CYGWIN__ */
void
OsInit(void)
@@ -155,6 +157,7 @@ OsInit(void)
char fname[PATH_MAX];
if (!been_here) {
+#if !defined(WIN32) || defined(__CYGWIN__)
struct sigaction act, oact;
int i;
@@ -181,6 +184,8 @@ OsInit(void)
siglist[i], strerror(errno));
}
}
+#endif /* !WIN32 || __CYGWIN__ */
+
#ifdef HAVE_BACKTRACE
/*
* initialize the backtracer, since the ctor calls dlopen(), which
@@ -207,29 +212,29 @@ OsInit(void)
fclose(stdin);
fclose(stdout);
#endif
- /*
- * If a write of zero bytes to stderr returns non-zero, i.e. -1,
- * then writing to stderr failed, and we'll write somewhere else
- * instead. (Apparently this never happens in the Real World.)
- */
- if (write(2, fname, 0) == -1) {
- FILE *err;
-
- if (strlen(display) + strlen(ADMPATH) + 1 < sizeof fname)
- snprintf(fname, sizeof(fname), ADMPATH, display);
- else
- strlcpy(fname, devnull, sizeof(fname));
- /*
- * uses stdio to avoid os dependencies here,
- * a real os would use
- * open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666)
- */
- if (!(err = fopen(fname, "a+")))
- err = fopen(devnull, "w");
- if (err && (fileno(err) != 2)) {
- dup2(fileno(err), 2);
- fclose(err);
- }
+ /*
+ * If a write of zero bytes to stderr returns non-zero, i.e. -1,
+ * then writing to stderr failed, and we'll write somewhere else
+ * instead. (Apparently this never happens in the Real World.)
+ */
+ if (write (2, fname, 0) == -1) {
+ FILE *err;
+
+ if (strlen (display) + strlen (ADMPATH) + 1 < sizeof fname)
+ snprintf (fname, sizeof(fname), ADMPATH, display);
+ else
+ strlcpy (fname, devnull, sizeof(fname));
+ /*
+ * uses stdio to avoid os dependencies here,
+ * a real os would use
+ * open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666)
+ */
+ if (!(err = fopen (fname, "a+")))
+ err = fopen (devnull, "w");
+ if (err && (fileno(err) != 2)) {
+ dup2 (fileno (err), 2);
+ fclose (err);
+ }
#if defined(SYSV) || defined(SVR4) || defined(WIN32) || defined(__CYGWIN__)
{
static char buf[BUFSIZ];
@@ -241,8 +246,10 @@ OsInit(void)
#endif
}
+#if !defined(WIN32) || defined(__CYGWIN__)
if (getpgrp() == 0)
setpgid(0, 0);
+#endif
#ifdef RLIMIT_DATA
if (limitDataSpace >= 0) {
@@ -288,6 +295,7 @@ OsInit(void)
}
TimerInit();
OsVendorInit();
+ OsResetSignals();
/*
* No log file by default. OsVendorInit() should call LogInit() with the
* log file name if logging to a file is desired.
diff --git a/xserver/os/strndup.c b/xserver/os/strndup.c
index b604b9bac..e0eddf13d 100644
--- a/xserver/os/strndup.c
+++ b/xserver/os/strndup.c
@@ -27,6 +27,10 @@
* SUCH DAMAGE.
*/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
diff --git a/xserver/os/utils.c b/xserver/os/utils.c
index 47a34b914..617431f14 100644
--- a/xserver/os/utils.c
+++ b/xserver/os/utils.c
@@ -71,6 +71,7 @@ __stdcall unsigned long GetTickCount(void);
#if !defined(WIN32) || !defined(__MINGW32__)
#include <sys/time.h>
#include <sys/resource.h>
+# define SMART_SCHEDULE_POSSIBLE
#endif
#include "misc.h"
#include <X11/X.h>
@@ -138,7 +139,6 @@ Bool noDPMSExtension = FALSE;
#endif
#ifdef GLXEXT
Bool noGlxExtension = FALSE;
-Bool noGlxVisualInit = FALSE;
#endif
#ifdef SCREENSAVER
Bool noScreenSaverExtension = FALSE;
@@ -204,6 +204,8 @@ int auditTrailLevel = 1;
char *SeatId = NULL;
+sig_atomic_t inSignalContext = FALSE;
+
#if defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
#define HAS_SAVED_IDS_AND_SETEUID
#endif
@@ -211,6 +213,9 @@ char *SeatId = NULL;
OsSigHandlerPtr
OsSignal(int sig, OsSigHandlerPtr handler)
{
+#if defined(WIN32) && !defined(__CYGWIN__)
+ return signal(sig, handler);
+#else
struct sigaction act, oact;
sigemptyset(&act.sa_mask);
@@ -221,6 +226,7 @@ OsSignal(int sig, OsSigHandlerPtr handler)
if (sigaction(sig, &act, &oact))
perror("sigaction");
return oact.sa_handler;
+#endif
}
/*
@@ -234,6 +240,19 @@ OsSignal(int sig, OsSigHandlerPtr handler)
#define LOCK_PREFIX "/.X"
#define LOCK_SUFFIX "-lock"
+#if !defined(WIN32) || defined(__CYGWIN__)
+#define LOCK_SERVER
+#endif
+
+#ifndef LOCK_SERVER
+void
+LockServer(void)
+{}
+
+void
+UnlockServer(void)
+{}
+#else /* LOCK_SERVER */
static Bool StillLocking = FALSE;
static char LockFile[PATH_MAX];
static Bool nolock = FALSE;
@@ -264,10 +283,8 @@ LockServer(void)
len += strlen(tmppath) + strlen(port) + strlen(LOCK_SUFFIX) + 1;
if (len > sizeof(LockFile))
FatalError("Display name `%s' is too long\n", port);
- (void) snprintf(tmp, sizeof(tmp),
- "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
- (void) snprintf(LockFile, sizeof(LockFile),
- "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
+ (void) sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
+ (void) sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port);
/*
* Create a temporary file containing our PID. Attempt three times
@@ -387,12 +404,13 @@ UnlockServer(void)
(void) unlink(LockFile);
}
}
+#endif /* LOCK_SERVER */
#ifdef X_PRIVSEP
int
ChownLock(uid_t uid, gid_t gid)
{
- return chown(LockFile, uid, gid);
+ return chown(LockFile, uid, gid);
}
#endif
@@ -516,7 +534,9 @@ UseMsg(void)
#ifdef RLIMIT_STACK
ErrorF("-ls int limit stack space to N Kb\n");
#endif
+#ifdef LOCK_SERVER
ErrorF("-nolock disable the locking mechanism\n");
+#endif
ErrorF("-nolisten string don't listen on protocol\n");
ErrorF("-noreset don't reset after last client exists\n");
ErrorF("-background [none] create root window with no background\n");
@@ -530,8 +550,7 @@ UseMsg(void)
#ifndef __OpenBSD__
ErrorF("-retro start with classic stipple and cursor\n");
#else
- ErrorF("-retard start with black background "
- "and no cursor\n");
+ ErrorF("-retard start with black background and no cursor\n");
#endif
ErrorF("-s # screen-saver timeout (minutes)\n");
ErrorF("-seat string seat to run on\n");
@@ -678,6 +697,17 @@ ProcessCommandLine(int argc, char *argv[])
else
UseMsg();
}
+ else if (strcmp(argv[i], "-displayfd") == 0) {
+ if (++i < argc) {
+ displayfd = atoi(argv[i]);
+ display = NULL;
+#ifdef LOCK_SERVER
+ nolock = TRUE;
+#endif
+ }
+ else
+ UseMsg();
+ }
#ifdef DPMSExtension
else if (strcmp(argv[i], "dpms") == 0)
/* ignored for compatibility */ ;
@@ -753,6 +783,7 @@ ProcessCommandLine(int argc, char *argv[])
UseMsg();
}
#endif
+#ifdef LOCK_SERVER
else if (strcmp(argv[i], "-nolock") == 0) {
#if !defined(WIN32) && !defined(__CYGWIN__)
if (getuid() != 0)
@@ -762,11 +793,12 @@ ProcessCommandLine(int argc, char *argv[])
#endif
nolock = TRUE;
}
+#endif
else if (strcmp(argv[i], "-nolisten") == 0) {
if (++i < argc) {
if (_XSERVTransNoListen(argv[i]))
- FatalError("Failed to disable listen for %s transport",
- argv[i]);
+ ErrorF("Failed to disable listen for %s transport",
+ argv[i]);
}
else
UseMsg();
@@ -796,11 +828,11 @@ ProcessCommandLine(int argc, char *argv[])
else if (strcmp(argv[i], "-r") == 0)
defaultKeyboardControl.autoRepeat = FALSE;
#ifndef __OpenBSD__
- else if (strcmp(argv[i], "-retro") == 0)
+ else if ( strcmp( argv[i], "-retro") == 0)
party_like_its_1989 = TRUE;
#else
- else if ( strcmp( argv[i], "-retard") == 0)
- party_like_its_1989 = FALSE;
+ else if ( strcmp( argv[i], "-retard") == 0)
+ party_like_its_1989 = FALSE;
#endif
else if (strcmp(argv[i], "-s") == 0) {
if (++i < argc)
@@ -888,6 +920,7 @@ ProcessCommandLine(int argc, char *argv[])
i = skip - 1;
}
#endif
+#ifdef SMART_SCHEDULE_POSSIBLE
else if (strcmp(argv[i], "-dumbSched") == 0) {
SmartScheduleDisable = TRUE;
}
@@ -906,6 +939,7 @@ ProcessCommandLine(int argc, char *argv[])
else
UseMsg();
}
+#endif
else if (strcmp(argv[i], "-render") == 0) {
if (++i < argc) {
int policy = PictureParseCmapPolicy(argv[i]);
@@ -1117,6 +1151,7 @@ XNFstrdup(const char *s)
void
SmartScheduleStopTimer(void)
{
+#ifdef SMART_SCHEDULE_POSSIBLE
struct itimerval timer;
if (SmartScheduleDisable)
@@ -1126,11 +1161,13 @@ SmartScheduleStopTimer(void)
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 0;
(void) setitimer(ITIMER_REAL, &timer, 0);
+#endif
}
void
SmartScheduleStartTimer(void)
{
+#ifdef SMART_SCHEDULE_POSSIBLE
struct itimerval timer;
if (SmartScheduleDisable)
@@ -1140,6 +1177,7 @@ SmartScheduleStartTimer(void)
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = SmartScheduleInterval * 1000;
setitimer(ITIMER_REAL, &timer, 0);
+#endif
}
static void
@@ -1151,6 +1189,7 @@ SmartScheduleTimer(int sig)
void
SmartScheduleInit(void)
{
+#ifdef SMART_SCHEDULE_POSSIBLE
struct sigaction act;
if (SmartScheduleDisable)
@@ -1166,6 +1205,7 @@ SmartScheduleInit(void)
perror("sigaction for smart scheduler");
SmartScheduleDisable = TRUE;
}
+#endif
}
#ifdef SIG_BLOCK
@@ -1180,15 +1220,15 @@ OsBlockSignals(void)
if (BlockedSignalCount++ == 0) {
sigset_t set;
+#ifdef SIGIO
+ OsBlockSIGIO();
+#endif
sigemptyset(&set);
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGVTALRM);
#ifdef SIGWINCH
sigaddset(&set, SIGWINCH);
#endif
-#ifdef SIGIO
- sigaddset(&set, SIGIO);
-#endif
sigaddset(&set, SIGTSTP);
sigaddset(&set, SIGTTIN);
sigaddset(&set, SIGTTOU);
@@ -1198,16 +1238,74 @@ OsBlockSignals(void)
#endif
}
+#ifdef SIG_BLOCK
+static sig_atomic_t sigio_blocked;
+static sigset_t PreviousSigIOMask;
+#endif
+
+/**
+ * returns zero if this call caused SIGIO to be blocked now, non-zero if it
+ * was already blocked by a previous call to this function.
+ */
+int
+OsBlockSIGIO(void)
+{
+#ifdef SIGIO
+#ifdef SIG_BLOCK
+ if (sigio_blocked++ == 0) {
+ sigset_t set;
+ int ret;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGIO);
+ sigprocmask(SIG_BLOCK, &set, &PreviousSigIOMask);
+ ret = sigismember(&PreviousSigIOMask, SIGIO);
+ return ret;
+ }
+#endif
+#endif
+ return 1;
+}
+
+void
+OsReleaseSIGIO(void)
+{
+#ifdef SIGIO
+#ifdef SIG_BLOCK
+ if (--sigio_blocked == 0) {
+ sigprocmask(SIG_SETMASK, &PreviousSigIOMask, 0);
+ } else if (sigio_blocked < 0) {
+ BUG_WARN(sigio_blocked < 0);
+ sigio_blocked = 0;
+ }
+#endif
+#endif
+}
+
void
OsReleaseSignals(void)
{
#ifdef SIG_BLOCK
if (--BlockedSignalCount == 0) {
sigprocmask(SIG_SETMASK, &PreviousSignalMask, 0);
+ OsReleaseSIGIO();
}
#endif
}
+void
+OsResetSignals(void)
+{
+#ifdef SIG_BLOCK
+ while (BlockedSignalCount > 0)
+ OsReleaseSignals();
+#ifdef SIGIO
+ while (sigio_blocked > 0)
+ OsReleaseSIGIO();
+#endif
+#endif
+}
+
/*
* Pending signals may interfere with core dumping. Provide a
* mechanism to block signals when aborting.
@@ -1514,6 +1612,79 @@ Fclose(pointer iop)
#endif /* !WIN32 */
+#ifdef WIN32
+
+#include <X11/Xwindows.h>
+
+const char *
+Win32TempDir()
+{
+ static char buffer[PATH_MAX];
+
+ if (GetTempPath(sizeof(buffer), buffer)) {
+ int len;
+
+ buffer[sizeof(buffer) - 1] = 0;
+ len = strlen(buffer);
+ if (len > 0)
+ if (buffer[len - 1] == '\\')
+ buffer[len - 1] = 0;
+ return buffer;
+ }
+ if (getenv("TEMP") != NULL)
+ return getenv("TEMP");
+ else if (getenv("TMP") != NULL)
+ return getenv("TMP");
+ else
+ return "/tmp";
+}
+
+int
+System(const char *cmdline)
+{
+ STARTUPINFO si;
+ PROCESS_INFORMATION pi;
+ DWORD dwExitCode;
+ char *cmd = strdup(cmdline);
+
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZeroMemory(&pi, sizeof(pi));
+
+ if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
+ LPVOID buffer;
+
+ if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &buffer, 0, NULL)) {
+ ErrorF("[xkb] Starting '%s' failed!\n", cmdline);
+ }
+ else {
+ ErrorF("[xkb] Starting '%s' failed: %s", cmdline, (char *) buffer);
+ LocalFree(buffer);
+ }
+
+ free(cmd);
+ return -1;
+ }
+ /* Wait until child process exits. */
+ WaitForSingleObject(pi.hProcess, INFINITE);
+
+ GetExitCodeProcess(pi.hProcess, &dwExitCode);
+
+ /* Close process and thread handles. */
+ CloseHandle(pi.hProcess);
+ CloseHandle(pi.hThread);
+ free(cmd);
+
+ return dwExitCode;
+}
+#endif
+
/*
* CheckUserParameters: check for long command line arguments and long
* environment variables. By default, these checks are only done when
@@ -1806,3 +1977,93 @@ xstrtokenize(const char *str, const char *separators)
free(list);
return NULL;
}
+
+/* Format a signed number into a string in a signal safe manner. The string
+ * should be at least 21 characters in order to handle all int64_t values.
+ */
+void
+FormatInt64(int64_t num, char *string)
+{
+ if (num < 0) {
+ string[0] = '-';
+ num *= -1;
+ string++;
+ }
+ FormatUInt64(num, string);
+}
+
+/* Format a number into a string in a signal safe manner. The string should be
+ * at least 21 characters in order to handle all uint64_t values. */
+void
+FormatUInt64(uint64_t num, char *string)
+{
+ uint64_t divisor;
+ int len;
+ int i;
+
+ for (len = 1, divisor = 10;
+ len < 20 && num / divisor;
+ len++, divisor *= 10);
+
+ for (i = len, divisor = 1; i > 0; i--, divisor *= 10)
+ string[i - 1] = '0' + ((num / divisor) % 10);
+
+ string[len] = '\0';
+}
+
+/**
+ * Format a double number as %.2f.
+ */
+void
+FormatDouble(double dbl, char *string)
+{
+ int slen = 0;
+ uint64_t frac;
+
+ frac = (dbl > 0 ? dbl : -dbl) * 100.0 + 0.5;
+ frac %= 100;
+
+ /* write decimal part to string */
+ if (dbl < 0 && dbl > -1)
+ string[slen++] = '-';
+ FormatInt64((int64_t)dbl, &string[slen]);
+
+ while(string[slen] != '\0')
+ slen++;
+
+ /* append fractional part, but only if we have enough characters. We
+ * expect string to be 21 chars (incl trailing \0) */
+ if (slen <= 17) {
+ string[slen++] = '.';
+ if (frac < 10)
+ string[slen++] = '0';
+
+ FormatUInt64(frac, &string[slen]);
+ }
+}
+
+
+/* Format a number into a hexadecimal string in a signal safe manner. The string
+ * should be at least 17 characters in order to handle all uint64_t values. */
+void
+FormatUInt64Hex(uint64_t num, char *string)
+{
+ uint64_t divisor;
+ int len;
+ int i;
+
+ for (len = 1, divisor = 0x10;
+ len < 16 && num / divisor;
+ len++, divisor *= 0x10);
+
+ for (i = len, divisor = 1; i > 0; i--, divisor *= 0x10) {
+ int val = (num / divisor) % 0x10;
+
+ if (val < 10)
+ string[i - 1] = '0' + val;
+ else
+ string[i - 1] = 'a' + val - 10;
+ }
+
+ string[len] = '\0';
+}
diff --git a/xserver/os/xdmcp.c b/xserver/os/xdmcp.c
index 8d0fbb5a9..0538ac53e 100644
--- a/xserver/os/xdmcp.c
+++ b/xserver/os/xdmcp.c
@@ -751,7 +751,7 @@ receive_packet(int socketfd)
XdmcpHeader header;
/* read message off socket */
- if (!XdmcpFill(socketfd, &buffer, (XdmcpNetaddr) & from, &fromlen))
+ if (!XdmcpFill(socketfd, &buffer, (XdmcpNetaddr) &from, &fromlen))
return;
/* reset retransmission backoff */
@@ -1059,7 +1059,7 @@ send_query_msg(void)
for (i = 0; i < NumBroadcastAddresses; i++)
XdmcpFlush(xdmcpSocket, &buffer,
- (XdmcpNetaddr) & BroadcastAddresses[i],
+ (XdmcpNetaddr) &BroadcastAddresses[i],
sizeof(struct sockaddr_in));
}
#if defined(IPv6) && defined(AF_INET6)
@@ -1098,7 +1098,7 @@ send_query_msg(void)
if (SOCKADDR_FAMILY(ManagerAddress) == AF_INET6)
socketfd = xdmcpSocket6;
#endif
- XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) & ManagerAddress,
+ XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) &ManagerAddress,
ManagerAddressLen);
}
}
@@ -1223,7 +1223,7 @@ send_request_msg(void)
socketfd = xdmcpSocket6;
#endif
if (XdmcpFlush(socketfd, &buffer,
- (XdmcpNetaddr) & req_sockaddr, req_socklen))
+ (XdmcpNetaddr) &req_sockaddr, req_socklen))
state = XDM_AWAIT_REQUEST_RESPONSE;
}
@@ -1316,7 +1316,7 @@ send_manage_msg(void)
if (SOCKADDR_FAMILY(req_sockaddr) == AF_INET6)
socketfd = xdmcpSocket6;
#endif
- XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) & req_sockaddr, req_socklen);
+ XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen);
}
static void
@@ -1373,7 +1373,7 @@ send_keepalive_msg(void)
if (SOCKADDR_FAMILY(req_sockaddr) == AF_INET6)
socketfd = xdmcpSocket6;
#endif
- XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) & req_sockaddr, req_socklen);
+ XdmcpFlush(socketfd, &buffer, (XdmcpNetaddr) &req_sockaddr, req_socklen);
}
static void
@@ -1391,7 +1391,7 @@ recv_alive_msg(unsigned length)
if (SessionRunning && AliveSessionID == SessionID) {
/* backoff dormancy period */
state = XDM_RUN_SESSION;
- if ((GetTimeInMillis() - lastDeviceEventTime.milliseconds) >
+ if ((GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds) >
keepaliveDormancy * 1000) {
keepaliveDormancy <<= 1;
if (keepaliveDormancy > XDM_MAX_DORMANCY)
diff --git a/xserver/os/xsha1.c b/xserver/os/xsha1.c
index dccce74b6..24c0aa284 100644
--- a/xserver/os/xsha1.c
+++ b/xserver/os/xsha1.c
@@ -74,6 +74,78 @@ x_sha1_final(void *ctx, unsigned char result[20])
return 1;
}
+#elif defined(HAVE_SHA1_IN_CRYPTOAPI) /* Use CryptoAPI for SHA1 */
+
+#define WIN32_LEAN_AND_MEAN
+#include <X11/Xwindows.h>
+#include <wincrypt.h>
+
+static HCRYPTPROV hProv;
+
+void *
+x_sha1_init(void)
+{
+ HCRYPTHASH *ctx = malloc(sizeof(*ctx));
+
+ if (!ctx)
+ return NULL;
+ CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
+ CryptCreateHash(hProv, CALG_SHA1, 0, 0, ctx);
+ return ctx;
+}
+
+int
+x_sha1_update(void *ctx, void *data, int size)
+{
+ HCRYPTHASH *hHash = ctx;
+
+ CryptHashData(*hHash, data, size, 0);
+ return 1;
+}
+
+int
+x_sha1_final(void *ctx, unsigned char result[20])
+{
+ HCRYPTHASH *hHash = ctx;
+ DWORD len = 20;
+
+ CryptGetHashParam(*hHash, HP_HASHVAL, result, &len, 0);
+ CryptDestroyHash(*hHash);
+ CryptReleaseContext(hProv, 0);
+ free(ctx);
+ return 1;
+}
+
+#elif defined(HAVE_SHA1_IN_LIBNETTLE) /* Use libnettle for SHA1 */
+
+#include <nettle/sha.h>
+
+void *
+x_sha1_init(void)
+{
+ struct sha1_ctx *ctx = malloc(sizeof(*ctx));
+
+ if (!ctx)
+ return NULL;
+ sha1_init(ctx);
+ return ctx;
+}
+
+int
+x_sha1_update(void *ctx, void *data, int size)
+{
+ sha1_update(ctx, size, data);
+ return 1;
+}
+
+int
+x_sha1_final(void *ctx, unsigned char result[20])
+{
+ sha1_digest(ctx, 20, result);
+ free(ctx);
+ return 1;
+}
+
#elif defined(HAVE_SHA1_IN_LIBGCRYPT) /* Use libgcrypt for SHA1 */
#include <gcrypt.h>