diff options
Diffstat (limited to 'os')
-rw-r--r-- | os/Makefile.am | 2 | ||||
-rw-r--r-- | os/backtrace.c | 47 | ||||
-rw-r--r-- | os/connection.c | 16 | ||||
-rw-r--r-- | os/log.c | 10 | ||||
-rw-r--r-- | os/osinit.c | 85 | ||||
-rw-r--r-- | os/utils.c | 42 |
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; @@ -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 /* |