osinit.c revision 6747b715
105b261ecSmrg/*********************************************************** 205b261ecSmrg 305b261ecSmrgCopyright 1987, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrg 2605b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 2705b261ecSmrg 2805b261ecSmrg All Rights Reserved 2905b261ecSmrg 3005b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3105b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3205b261ecSmrgprovided that the above copyright notice appear in all copies and that 3305b261ecSmrgboth that copyright notice and this permission notice appear in 3405b261ecSmrgsupporting documentation, and that the name of Digital not be 3505b261ecSmrgused in advertising or publicity pertaining to distribution of the 3605b261ecSmrgsoftware without specific, written prior permission. 3705b261ecSmrg 3805b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3905b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 4005b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4105b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4205b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4305b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4405b261ecSmrgSOFTWARE. 4505b261ecSmrg 4605b261ecSmrg******************************************************************/ 4705b261ecSmrg 4805b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 4905b261ecSmrg#include <dix-config.h> 5005b261ecSmrg#endif 5105b261ecSmrg 5205b261ecSmrg#include <stdio.h> 5305b261ecSmrg#include <X11/X.h> 5405b261ecSmrg#include "os.h" 5505b261ecSmrg#include "osdep.h" 5605b261ecSmrg#include <X11/Xos.h> 576747b715Smrg#include <signal.h> 586747b715Smrg#include <errno.h> 596747b715Smrg#ifdef HAVE_DLFCN_H 606747b715Smrg# include <dlfcn.h> 616747b715Smrg#endif 626747b715Smrg#ifdef HAVE_BACKTRACE 636747b715Smrg#include <execinfo.h> 646747b715Smrg#endif 656747b715Smrg 6605b261ecSmrg 6705b261ecSmrg#include "dixstruct.h" 6805b261ecSmrg 6905b261ecSmrg#ifndef PATH_MAX 7005b261ecSmrg#ifdef MAXPATHLEN 7105b261ecSmrg#define PATH_MAX MAXPATHLEN 7205b261ecSmrg#else 7305b261ecSmrg#define PATH_MAX 1024 7405b261ecSmrg#endif 7505b261ecSmrg#endif 7605b261ecSmrg 774642e01fSmrg#if defined(__SCO__) 7805b261ecSmrg#include <sys/wait.h> 7905b261ecSmrg#endif 8005b261ecSmrg 814642e01fSmrg#if !defined(SYSV) && !defined(WIN32) 8205b261ecSmrg#include <sys/resource.h> 8305b261ecSmrg#endif 8405b261ecSmrg 8505b261ecSmrg#ifndef ADMPATH 8605b261ecSmrg#define ADMPATH "/usr/adm/X%smsgs" 8705b261ecSmrg#endif 8805b261ecSmrg 8905b261ecSmrgextern char *display; 9005b261ecSmrg#ifdef RLIMIT_DATA 9105b261ecSmrgint limitDataSpace = -1; 9205b261ecSmrg#endif 9305b261ecSmrg#ifdef RLIMIT_STACK 9405b261ecSmrgint limitStackSpace = -1; 9505b261ecSmrg#endif 9605b261ecSmrg#ifdef RLIMIT_NOFILE 9705b261ecSmrgint limitNoFile = -1; 9805b261ecSmrg#endif 9905b261ecSmrg 1006747b715Smrgstatic OsSigWrapperPtr OsSigWrapper = NULL; 1016747b715Smrg 1026747b715SmrgOsSigWrapperPtr 1036747b715SmrgOsRegisterSigWrapper(OsSigWrapperPtr newSigWrapper) 1046747b715Smrg{ 1056747b715Smrg OsSigWrapperPtr oldSigWrapper = OsSigWrapper; 1066747b715Smrg 1076747b715Smrg OsSigWrapper = newSigWrapper; 1086747b715Smrg 1096747b715Smrg return oldSigWrapper; 1106747b715Smrg} 1116747b715Smrg 1126747b715Smrg/* 1136747b715Smrg * OsSigHandler -- 1146747b715Smrg * Catch unexpected signals and exit or continue cleanly. 1156747b715Smrg */ 1166747b715Smrgstatic void 1176747b715Smrg#ifdef SA_SIGINFO 1186747b715SmrgOsSigHandler(int signo, siginfo_t *sip, void *unused) 1196747b715Smrg#else 1206747b715SmrgOsSigHandler(int signo) 1216747b715Smrg#endif 1226747b715Smrg{ 1236747b715Smrg#ifdef RTLD_DI_SETSIGNAL 1246747b715Smrg const char *dlerr = dlerror(); 1256747b715Smrg 1266747b715Smrg if (dlerr) { 1276747b715Smrg LogMessage(X_ERROR, "Dynamic loader error: %s\n", dlerr); 1286747b715Smrg } 1296747b715Smrg#endif /* RTLD_DI_SETSIGNAL */ 1306747b715Smrg 1316747b715Smrg if (OsSigWrapper != NULL) { 1326747b715Smrg if (OsSigWrapper(signo) == 0) { 1336747b715Smrg /* ddx handled signal and wants us to continue */ 1346747b715Smrg return; 1356747b715Smrg } 1366747b715Smrg } 1376747b715Smrg 1386747b715Smrg /* log, cleanup, and abort */ 1396747b715Smrg xorg_backtrace(); 1406747b715Smrg 1416747b715Smrg#ifdef SA_SIGINFO 1426747b715Smrg if (sip->si_code == SI_USER) { 1436747b715Smrg ErrorF("Recieved signal %d sent by process %ld, uid %ld\n", 1446747b715Smrg signo, (long) sip->si_pid, (long) sip->si_uid); 1456747b715Smrg } else { 1466747b715Smrg switch (signo) { 1476747b715Smrg case SIGSEGV: 1486747b715Smrg case SIGBUS: 1496747b715Smrg case SIGILL: 1506747b715Smrg case SIGFPE: 1516747b715Smrg ErrorF("%s at address %p\n", strsignal(signo), sip->si_addr); 1526747b715Smrg } 1536747b715Smrg } 1546747b715Smrg#endif 1556747b715Smrg 1566747b715Smrg FatalError("Caught signal %d (%s). Server aborting\n", 1576747b715Smrg signo, strsignal(signo)); 1586747b715Smrg} 1596747b715Smrg 16005b261ecSmrgvoid 16105b261ecSmrgOsInit(void) 16205b261ecSmrg{ 16305b261ecSmrg static Bool been_here = FALSE; 16405b261ecSmrg static char* devnull = "/dev/null"; 16505b261ecSmrg char fname[PATH_MAX]; 16605b261ecSmrg 1676747b715Smrg if (!been_here) { 1686747b715Smrg struct sigaction act, oact; 1696747b715Smrg int i; 1706747b715Smrg int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS, 1716747b715Smrg#ifdef SIGSYS 1726747b715Smrg SIGSYS, 1736747b715Smrg#endif 1746747b715Smrg#ifdef SIGXCPU 1756747b715Smrg SIGXCPU, 1766747b715Smrg#endif 1776747b715Smrg#ifdef SIGXFSZ 1786747b715Smrg SIGXFSZ, 1796747b715Smrg#endif 1806747b715Smrg#ifdef SIGEMT 1816747b715Smrg SIGEMT, 1826747b715Smrg#endif 1836747b715Smrg 0 /* must be last */ }; 1846747b715Smrg sigemptyset(&act.sa_mask); 1856747b715Smrg#ifdef SA_SIGINFO 1866747b715Smrg act.sa_sigaction = OsSigHandler; 1876747b715Smrg act.sa_flags = SA_SIGINFO; 1886747b715Smrg#else 1896747b715Smrg act.sa_handler = OsSigHandler; 1906747b715Smrg act.sa_flags = 0; 1916747b715Smrg#endif 1926747b715Smrg for (i = 0; siglist[i] != 0; i++) { 1936747b715Smrg if (sigaction(siglist[i], &act, &oact)) { 1946747b715Smrg ErrorF("failed to install signal handler for signal %d: %s\n", 1956747b715Smrg siglist[i], strerror(errno)); 1966747b715Smrg } 1976747b715Smrg } 1986747b715Smrg#ifdef HAVE_BACKTRACE 1996747b715Smrg /* 2006747b715Smrg * initialize the backtracer, since the ctor calls dlopen(), which 2016747b715Smrg * calls malloc(), which isn't signal-safe. 2026747b715Smrg */ 2036747b715Smrg do { 2046747b715Smrg void *array; 2056747b715Smrg backtrace(&array, 1); 2066747b715Smrg } while (0); 2076747b715Smrg#endif 2086747b715Smrg 2096747b715Smrg#ifdef RTLD_DI_SETSIGNAL 2106747b715Smrg /* Tell runtime linker to send a signal we can catch instead of SIGKILL 2116747b715Smrg * for failures to load libraries/modules at runtime so we can clean up 2126747b715Smrg * after ourselves. 2136747b715Smrg */ 2146747b715Smrg int failure_signal = SIGQUIT; 2156747b715Smrg dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal); 21605b261ecSmrg#endif 21705b261ecSmrg 21805b261ecSmrg#if !defined(__SCO__) && !defined(__CYGWIN__) && !defined(__UNIXWARE__) 21905b261ecSmrg fclose(stdin); 22005b261ecSmrg fclose(stdout); 22105b261ecSmrg#endif 22205b261ecSmrg /* 22305b261ecSmrg * If a write of zero bytes to stderr returns non-zero, i.e. -1, 22405b261ecSmrg * then writing to stderr failed, and we'll write somewhere else 22505b261ecSmrg * instead. (Apparently this never happens in the Real World.) 22605b261ecSmrg */ 22705b261ecSmrg if (write (2, fname, 0) == -1) 22805b261ecSmrg { 22905b261ecSmrg FILE *err; 23005b261ecSmrg 2316747b715Smrg if (strlen (display) + strlen (ADMPATH) + 1 < sizeof fname) 2326747b715Smrg sprintf (fname, ADMPATH, display); 23305b261ecSmrg else 23405b261ecSmrg strcpy (fname, devnull); 23505b261ecSmrg /* 23605b261ecSmrg * uses stdio to avoid os dependencies here, 23705b261ecSmrg * a real os would use 23805b261ecSmrg * open (fname, O_WRONLY|O_APPEND|O_CREAT, 0666) 23905b261ecSmrg */ 24005b261ecSmrg if (!(err = fopen (fname, "a+"))) 24105b261ecSmrg err = fopen (devnull, "w"); 24205b261ecSmrg if (err && (fileno(err) != 2)) { 24305b261ecSmrg dup2 (fileno (err), 2); 24405b261ecSmrg fclose (err); 24505b261ecSmrg } 24605b261ecSmrg#if defined(SYSV) || defined(SVR4) || defined(WIN32) || defined(__CYGWIN__) 24705b261ecSmrg { 24805b261ecSmrg static char buf[BUFSIZ]; 24905b261ecSmrg setvbuf (stderr, buf, _IOLBF, BUFSIZ); 25005b261ecSmrg } 25105b261ecSmrg#else 25205b261ecSmrg setlinebuf(stderr); 25305b261ecSmrg#endif 25405b261ecSmrg } 25505b261ecSmrg 25605b261ecSmrg if (getpgrp () == 0) 25705b261ecSmrg setpgid (0, 0); 25805b261ecSmrg 25905b261ecSmrg#ifdef RLIMIT_DATA 26005b261ecSmrg if (limitDataSpace >= 0) 26105b261ecSmrg { 26205b261ecSmrg struct rlimit rlim; 26305b261ecSmrg 26405b261ecSmrg if (!getrlimit(RLIMIT_DATA, &rlim)) 26505b261ecSmrg { 26605b261ecSmrg if ((limitDataSpace > 0) && (limitDataSpace < rlim.rlim_max)) 26705b261ecSmrg rlim.rlim_cur = limitDataSpace; 26805b261ecSmrg else 26905b261ecSmrg rlim.rlim_cur = rlim.rlim_max; 27005b261ecSmrg (void)setrlimit(RLIMIT_DATA, &rlim); 27105b261ecSmrg } 27205b261ecSmrg } 27305b261ecSmrg#endif 27405b261ecSmrg#ifdef RLIMIT_STACK 27505b261ecSmrg if (limitStackSpace >= 0) 27605b261ecSmrg { 27705b261ecSmrg struct rlimit rlim; 27805b261ecSmrg 27905b261ecSmrg if (!getrlimit(RLIMIT_STACK, &rlim)) 28005b261ecSmrg { 28105b261ecSmrg if ((limitStackSpace > 0) && (limitStackSpace < rlim.rlim_max)) 28205b261ecSmrg rlim.rlim_cur = limitStackSpace; 28305b261ecSmrg else 28405b261ecSmrg rlim.rlim_cur = rlim.rlim_max; 28505b261ecSmrg (void)setrlimit(RLIMIT_STACK, &rlim); 28605b261ecSmrg } 28705b261ecSmrg } 28805b261ecSmrg#endif 28905b261ecSmrg#ifdef RLIMIT_NOFILE 29005b261ecSmrg if (limitNoFile >= 0) 29105b261ecSmrg { 29205b261ecSmrg struct rlimit rlim; 29305b261ecSmrg 29405b261ecSmrg if (!getrlimit(RLIMIT_NOFILE, &rlim)) 29505b261ecSmrg { 29605b261ecSmrg if ((limitNoFile > 0) && (limitNoFile < rlim.rlim_max)) 29705b261ecSmrg rlim.rlim_cur = limitNoFile; 29805b261ecSmrg else 29905b261ecSmrg rlim.rlim_cur = rlim.rlim_max; 30005b261ecSmrg (void)setrlimit(RLIMIT_NOFILE, &rlim); 30105b261ecSmrg } 30205b261ecSmrg } 30305b261ecSmrg#endif 30405b261ecSmrg LockServer(); 30505b261ecSmrg been_here = TRUE; 30605b261ecSmrg } 30705b261ecSmrg TimerInit(); 30805b261ecSmrg OsVendorInit(); 30905b261ecSmrg /* 31005b261ecSmrg * No log file by default. OsVendorInit() should call LogInit() with the 31105b261ecSmrg * log file name if logging to a file is desired. 31205b261ecSmrg */ 31305b261ecSmrg LogInit(NULL, NULL); 31405b261ecSmrg if (!SmartScheduleDisable) 31505b261ecSmrg if (!SmartScheduleInit ()) 31605b261ecSmrg SmartScheduleDisable = TRUE; 31705b261ecSmrg} 31805b261ecSmrg 31905b261ecSmrgvoid 32005b261ecSmrgOsCleanup(Bool terminating) 32105b261ecSmrg{ 32205b261ecSmrg if (terminating) 32305b261ecSmrg { 32405b261ecSmrg UnlockServer(); 32505b261ecSmrg } 32605b261ecSmrg} 327