summaryrefslogtreecommitdiff
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/Makefile.am2
-rw-r--r--os/backtrace.c47
-rw-r--r--os/connection.c16
-rw-r--r--os/log.c10
-rw-r--r--os/osinit.c85
-rw-r--r--os/utils.c42
6 files changed, 130 insertions, 72 deletions
diff --git a/os/Makefile.am b/os/Makefile.am
index 88914852f..30ce9e1be 100644
--- a/os/Makefile.am
+++ b/os/Makefile.am
@@ -1,6 +1,6 @@
noinst_LTLIBRARIES = libos.la
-AM_CFLAGS = $(DIX_CFLAGS) $(SHA1_CFLAGS)
+AM_CFLAGS = $(DIX_CFLAGS) $(SHA1_CFLAGS) -DBINDIR=\"$(bindir)\"
SECURERPC_SRCS = rpcauth.c
XDMCP_SRCS = xdmcp.c
diff --git a/os/backtrace.c b/os/backtrace.c
index daac60cf6..76aa6b2f3 100644
--- a/os/backtrace.c
+++ b/os/backtrace.c
@@ -30,6 +30,12 @@
#include <errno.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
#ifdef HAVE_BACKTRACE
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
@@ -147,9 +153,12 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
}
#endif /* HAVE_WALKCONTEXT */
-#ifdef HAVE_PSTACK
+/*
+ fork/exec a program to create a backtrace
+ Returns 0 if successful.
+*/
static int
-xorg_backtrace_pstack(void)
+xorg_backtrace_exec_wrapper(const char *path)
{
pid_t kidpid;
int pipefd[2];
@@ -158,7 +167,7 @@ xorg_backtrace_pstack(void)
return -1;
}
- kidpid = fork1();
+ kidpid = fork();
if (kidpid == -1) {
/* ERROR */
@@ -171,11 +180,13 @@ xorg_backtrace_pstack(void)
seteuid(0);
close(STDIN_FILENO);
close(STDOUT_FILENO);
+ close(STDERR_FILENO);
dup2(pipefd[1], STDOUT_FILENO);
- closefrom(STDERR_FILENO);
+ dup2(pipefd[1], STDERR_FILENO);
+ close(pipefd[1]);
snprintf(parent, sizeof(parent), "%d", getppid());
- execle("/usr/bin/pstack", "pstack", parent, NULL);
+ execle(path, path, parent, NULL, NULL);
exit(1);
}
else {
@@ -194,17 +205,34 @@ xorg_backtrace_pstack(void)
btline[bytesread] = 0;
ErrorFSigSafe("%s", btline);
}
- else if ((bytesread < 0) || ((errno != EINTR) && (errno != EAGAIN)))
+ else if ((bytesread == 0) ||
+ ((errno != EINTR) && (errno != EAGAIN)))
done = 1;
}
close(pipefd[0]);
waitpid(kidpid, &kidstat, 0);
- if (kidstat != 0)
+ if (!(WIFEXITED(kidstat) && WEXITSTATUS(kidstat) == 0)) {
+ ErrorFSigSafe("%s failed with returncode %d\n", path,
+ WEXITSTATUS(kidstat));
return -1;
+ }
}
return 0;
}
-#endif /* HAVE_PSTACK */
+
+#ifdef HAVE_PSTACK
+static int
+xorg_backtrace_pstack(void)
+{
+ return xorg_backtrace_exec_wrapper("/usr/bin/pstack");
+}
+#endif
+
+static int
+xorg_backtrace_script(void)
+{
+ return xorg_backtrace_exec_wrapper(BINDIR "/xorg-backtrace");
+}
#if defined(HAVE_PSTACK) || defined(HAVE_WALKCONTEXT)
@@ -241,7 +269,8 @@ xorg_backtrace(void)
void
xorg_backtrace(void)
{
- return;
+ if (xorg_backtrace_script() == 0)
+ return;
}
#endif
diff --git a/os/connection.c b/os/connection.c
index 721ad65b3..669c25566 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -269,6 +269,21 @@ lookup_trans_conn(int fd)
return NULL;
}
+int
+TransIsListening(char *protocol)
+{
+ /* look for this transport in the list of listeners */
+ int i;
+
+ for (i = 0; i < ListenTransCount; i++) {
+ if (!strcmp(protocol, ListenTransConns[i]->transptr->TransName)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/* Set MaxClients and lastfdesc, and allocate ConnectionTranslation */
void
@@ -415,6 +430,7 @@ CreateWellKnownSockets(void)
else { /* -displayfd */
Bool found = 0;
for (i = 0; i < 65535 - X_TCP_PORT; i++) {
+ ErrorF("Trying to create socket for display number %d\n", i);
if (TryCreateSocket(i, &partial) && !partial) {
found = 1;
break;
diff --git a/os/log.c b/os/log.c
index 4820e9a77..0ff076a64 100644
--- a/os/log.c
+++ b/os/log.c
@@ -216,6 +216,9 @@ LogInit(const char *fname, const char *backup)
free(oldLog);
}
}
+ else {
+ unlink(logFileName);
+ }
if ((logFile = fopen(logFileName, "w")) == NULL)
FatalError("Cannot open log file \"%s\"\n", logFileName);
setvbuf(logFile, NULL, _IONBF, 0);
@@ -763,9 +766,9 @@ FatalError(const char *f, ...)
static Bool beenhere = FALSE;
if (beenhere)
- ErrorF("\nFatalError re-entered, aborting\n");
+ ErrorF("FatalError re-entered, aborting\n");
else
- ErrorF("\nFatal server error:\n");
+ ErrorF("Fatal server error: ");
va_start(args, f);
@@ -784,7 +787,8 @@ FatalError(const char *f, ...)
#endif
VErrorF(f, args);
va_end(args);
- ErrorF("\n");
+ if (f[strlen(f) - 1] != '\n')
+ ErrorF("\n");
if (!beenhere)
OsVendorFatalError(f, args2);
va_end(args2);
diff --git a/os/osinit.c b/os/osinit.c
index 2eb1f7a8f..005c6efbe 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -70,10 +70,6 @@ SOFTWARE.
#include <sys/resource.h>
#endif
-#ifndef ADMPATH
-#define ADMPATH "/usr/adm/X%smsgs"
-#endif
-
extern char *display;
#ifdef RLIMIT_DATA
@@ -85,6 +81,7 @@ int limitStackSpace = -1;
#ifdef RLIMIT_NOFILE
int limitNoFile = -1;
#endif
+extern Bool install_os_signal_handler;
static OsSigWrapperPtr OsSigWrapper = NULL;
@@ -124,8 +121,7 @@ OsSigHandler(int signo)
}
}
- /* log, cleanup, and abort */
- xorg_backtrace();
+ ErrorF("Fatal signal received in thread 0x%x\n", pthread_self());
#ifdef SA_SIGINFO
if (sip->si_code == SI_USER) {
@@ -143,6 +139,9 @@ OsSigHandler(int signo)
}
#endif
+ /* log, cleanup, and abort */
+ xorg_backtrace();
+
FatalError("Caught signal %d (%s). Server aborting\n",
signo, strsignal(signo));
}
@@ -155,30 +154,33 @@ OsInit(void)
char fname[PATH_MAX];
if (!been_here) {
- struct sigaction act, oact;
- int i;
-
- int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS,
- SIGSYS,
- SIGXCPU,
- SIGXFSZ,
+ if (install_os_signal_handler) {
+ struct sigaction act, oact;
+ int i;
+
+ int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS,
+ SIGSYS,
+ SIGXCPU,
+ SIGXFSZ,
#ifdef SIGEMT
- SIGEMT,
+ SIGEMT,
#endif
- 0 /* must be last */
- };
- sigemptyset(&act.sa_mask);
+ 0 /* must be last */
+ };
+ sigemptyset(&act.sa_mask);
#ifdef SA_SIGINFO
- act.sa_sigaction = OsSigHandler;
- act.sa_flags = SA_SIGINFO;
+ act.sa_sigaction = OsSigHandler;
+ act.sa_flags = SA_SIGINFO;
#else
- act.sa_handler = OsSigHandler;
- act.sa_flags = 0;
+ act.sa_handler = OsSigHandler;
+ act.sa_flags = 0;
#endif
- for (i = 0; siglist[i] != 0; i++) {
- if (sigaction(siglist[i], &act, &oact)) {
- ErrorF("failed to install signal handler for signal %d: %s\n",
- siglist[i], strerror(errno));
+ for (i = 0; siglist[i] != 0; i++) {
+ if (sigaction(siglist[i], &act, &oact)) {
+ ErrorF
+ ("failed to install signal handler for signal %d: %s\n",
+ siglist[i], strerror(errno));
+ }
}
}
#ifdef HAVE_BACKTRACE
@@ -207,39 +209,6 @@ 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
- strcpy(fname, devnull);
- /*
- * 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];
-
- setvbuf(stderr, buf, _IOLBF, BUFSIZ);
- }
-#else
- setlinebuf(stderr);
-#endif
- }
if (getpgrp() == 0)
setpgid(0, 0);
diff --git a/os/utils.c b/os/utils.c
index 04bcbc61f..7d81d6945 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -121,6 +121,8 @@ __stdcall unsigned long GetTickCount(void);
#include "picture.h"
+Bool install_os_signal_handler = TRUE;
+
Bool noTestExtensions;
#ifdef COMPOSITE
@@ -237,7 +239,7 @@ OsSignal(int sig, OsSigHandlerPtr handler)
static Bool StillLocking = FALSE;
static char LockFile[PATH_MAX];
-static Bool nolock = FALSE;
+Bool nolock = FALSE;
/*
* LockServer --
@@ -503,6 +505,7 @@ UseMsg(void)
#ifdef RLIMIT_STACK
ErrorF("-ls int limit stack space to N Kb\n");
#endif
+ ErrorF("-notrapsignals disable catching of fatal signals\n");
ErrorF("-nolock disable the locking mechanism\n");
ErrorF("-nolisten string don't listen on protocol\n");
ErrorF("-noreset don't reset after last client exists\n");
@@ -744,6 +747,9 @@ ProcessCommandLine(int argc, char *argv[])
UseMsg();
}
#endif
+ else if (strcmp(argv[i], "-notrapsignals") == 0) {
+ install_os_signal_handler = FALSE;
+ }
else if (strcmp(argv[i], "-nolock") == 0) {
#if !defined(WIN32) && !defined(__CYGWIN__)
if (getuid() != 0)
@@ -879,6 +885,7 @@ ProcessCommandLine(int argc, char *argv[])
}
else if (strcmp(argv[i], "-schedInterval") == 0) {
if (++i < argc) {
+ SmartScheduleDisable = FALSE;
SmartScheduleInterval = atoi(argv[i]);
SmartScheduleSlice = SmartScheduleInterval;
}
@@ -887,6 +894,7 @@ ProcessCommandLine(int argc, char *argv[])
}
else if (strcmp(argv[i], "-schedMax") == 0) {
if (++i < argc) {
+ SmartScheduleDisable = FALSE;
SmartScheduleMaxSlice = atoi(argv[i]);
}
else
@@ -1277,6 +1285,26 @@ OsAbort(void)
* as well. As it is now, xkbcomp messages don't end up in the log file.
*/
+#ifdef __CYGWIN__
+#include <process.h>
+int
+System(const char *command)
+{
+ int status;
+
+ if (!command)
+ return 1;
+
+ DebugF("System: `%s'\n", command);
+
+ /*
+ Use spawnl() rather than execl() to implement System() on cygwin to
+ avoid fork emulation overhead and brittleness
+ */
+ status = spawnl(_P_WAIT, "/bin/sh", "sh", "-c", command, (char *) NULL);
+ return status;
+}
+#else
int
System(const char *command)
{
@@ -1318,6 +1346,7 @@ System(const char *command)
return p == -1 ? -1 : status;
}
+#endif
static struct pid {
struct pid *next;
@@ -1629,6 +1658,17 @@ System(const char *cmdline)
return dwExitCode;
}
+#elif defined(__CYGWIN__)
+const char*
+Win32TempDir(void)
+{
+ if (getenv("TEMP") != NULL)
+ return getenv("TEMP");
+ else if (getenv("TMP") != NULL)
+ return getenv("TEMP");
+ else
+ return "/tmp";
+}
#endif
/*