summaryrefslogtreecommitdiff
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/Makefile.am2
-rw-r--r--os/backtrace.c54
-rw-r--r--os/connection.c25
-rw-r--r--os/log.c7
-rw-r--r--os/osinit.c86
-rw-r--r--os/utils.c44
6 files changed, 140 insertions, 78 deletions
diff --git a/os/Makefile.am b/os/Makefile.am
index a1bbb4d1e..0b0eb79d1 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 3d1195b86..3100d1a13 100644
--- a/os/backtrace.c
+++ b/os/backtrace.c
@@ -222,10 +222,25 @@ xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
}
#endif /* HAVE_WALKCONTEXT */
-#ifdef HAVE_PSTACK
+#include <sys/types.h>
+#if !defined(__WIN32__) || defined(__CYGWIN__)
+#include <sys/wait.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ 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)
{
+#if defined(WIN32) && !defined(__CYGWIN__)
+ ErrorFSigSafe("Backtrace not implemented on Windows");
+ return -1;
+#else
pid_t kidpid;
int pipefd[2];
@@ -233,7 +248,7 @@ xorg_backtrace_pstack(void)
return -1;
}
- kidpid = fork1();
+ kidpid = fork();
if (kidpid == -1) {
/* ERROR */
@@ -246,11 +261,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 {
@@ -269,17 +286,35 @@ 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
+}
+
+#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");
}
-#endif /* HAVE_PSTACK */
#if defined(HAVE_PSTACK) || defined(HAVE_WALKCONTEXT)
@@ -316,7 +351,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 162e1d93e..20a9f008d 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
@@ -351,8 +366,8 @@ void
NotifyParentProcess(void)
{
#if !defined(WIN32)
- if (dynamic_display[0]) {
- write(displayfd, dynamic_display, strlen(dynamic_display));
+ if (displayfd) {
+ write(displayfd, display, strlen(display));
write(displayfd, "\n", 1);
close(displayfd);
}
@@ -404,9 +419,8 @@ CreateWellKnownSockets(void)
FD_ZERO(&WellKnownConnections);
/* 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) {
+ * number if specified on the command line. */
+ if ((displayfd == 0) || explicit_display) {
if (TryCreateSocket(atoi(display), &partial) &&
ListenTransCount >= 1)
if (!PartialNetwork && partial)
@@ -415,6 +429,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 53b358629..976f90f40 100644
--- a/os/log.c
+++ b/os/log.c
@@ -881,9 +881,9 @@ FatalError(const char *f, ...)
static Bool beenhere = FALSE;
if (beenhere)
- ErrorFSigSafe("\nFatalError re-entered, aborting\n");
+ ErrorFSigSafe("FatalError re-entered, aborting\n");
else
- ErrorFSigSafe("\nFatal server error:\n");
+ ErrorFSigSafe("Fatal server error: ");
va_start(args, f);
@@ -902,7 +902,8 @@ FatalError(const char *f, ...)
#endif
VErrorFSigSafe(f, args);
va_end(args);
- ErrorFSigSafe("\n");
+ if (f[strlen(f) - 1] != '\n')
+ ErrorFSigSafe("\n");
if (!beenhere)
OsVendorFatalError(f, args2);
va_end(args2);
diff --git a/os/osinit.c b/os/osinit.c
index 4d48ea94e..2791b53f2 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -69,10 +69,7 @@ SOFTWARE.
#if !defined(SYSV) && !defined(WIN32)
#include <sys/resource.h>
#endif
-
-#ifndef ADMPATH
-#define ADMPATH "/usr/adm/X%smsgs"
-#endif
+#include <pthread.h>
extern char *display;
@@ -85,6 +82,7 @@ int limitStackSpace = -1;
#ifdef RLIMIT_NOFILE
int limitNoFile = -1;
#endif
+extern Bool install_os_signal_handler;
static OsSigWrapperPtr OsSigWrapper = NULL;
@@ -125,8 +123,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) {
@@ -144,6 +141,9 @@ OsSigHandler(int signo)
}
#endif
+ /* log, cleanup, and abort */
+ xorg_backtrace();
+
FatalError("Caught signal %d (%s). Server aborting\n",
signo, strsignal(signo));
}
@@ -160,30 +160,33 @@ OsInit(void)
if (!been_here) {
#if !defined(WIN32) || defined(__CYGWIN__)
- 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));
+ }
}
}
#endif /* !WIN32 || __CYGWIN__ */
@@ -224,40 +227,7 @@ OsInit(void)
# elif !defined(__CYGWIN__)
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
- }
#endif /* !XQUARTZ */
#if !defined(WIN32) || defined(__CYGWIN__)
diff --git a/os/utils.c b/os/utils.c
index 608ee6ab0..d3391215b 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -122,6 +122,8 @@ __stdcall unsigned long GetTickCount(void);
#include "picture.h"
+Bool install_os_signal_handler = TRUE;
+
Bool noTestExtensions;
#ifdef COMPOSITE
@@ -253,7 +255,7 @@ UnlockServer(void)
#else /* LOCK_SERVER */
static Bool StillLocking = FALSE;
static char LockFile[PATH_MAX];
-static Bool nolock = FALSE;
+Bool nolock = FALSE;
/*
* LockServer --
@@ -547,6 +549,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");
#ifdef LOCK_SERVER
ErrorF("-nolock disable the locking mechanism\n");
#endif
@@ -639,6 +642,7 @@ ProcessCommandLine(int argc, char *argv[])
else if (argv[i][0] == ':') {
/* initialize display */
display = argv[i];
+ explicit_display = TRUE;
display++;
if (!VerifyDisplayName(display)) {
ErrorF("Bad display name: %s\n", display);
@@ -709,7 +713,6 @@ ProcessCommandLine(int argc, char *argv[])
else if (strcmp(argv[i], "-displayfd") == 0) {
if (++i < argc) {
displayfd = atoi(argv[i]);
- display = NULL;
#ifdef LOCK_SERVER
nolock = TRUE;
#endif
@@ -792,6 +795,9 @@ ProcessCommandLine(int argc, char *argv[])
UseMsg();
}
#endif
+ else if (strcmp(argv[i], "-notrapsignals") == 0) {
+ install_os_signal_handler = FALSE;
+ }
#ifdef LOCK_SERVER
else if (strcmp(argv[i], "-nolock") == 0) {
#if !defined(WIN32) && !defined(__CYGWIN__)
@@ -930,6 +936,7 @@ ProcessCommandLine(int argc, char *argv[])
}
else if (strcmp(argv[i], "-schedInterval") == 0) {
if (++i < argc) {
+ SmartScheduleDisable = FALSE;
SmartScheduleInterval = atoi(argv[i]);
SmartScheduleSlice = SmartScheduleInterval;
}
@@ -938,6 +945,7 @@ ProcessCommandLine(int argc, char *argv[])
}
else if (strcmp(argv[i], "-schedMax") == 0) {
if (++i < argc) {
+ SmartScheduleDisable = FALSE;
SmartScheduleMaxSlice = atoi(argv[i]);
}
else
@@ -1335,6 +1343,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)
{
@@ -1376,6 +1404,7 @@ System(const char *command)
return p == -1 ? -1 : status;
}
+#endif
static struct pid {
struct pid *next;
@@ -1687,6 +1716,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("TMP");
+ else
+ return "/tmp";
+}
#endif
/*