diff --git a/config/udev.c b/config/udev.c index 9ac34ee50..e7383dc36 100644 --- a/config/udev.c +++ b/config/udev.c @@ -251,14 +251,12 @@ wakeup_handler(pointer data, int err, pointer read_mask) return; action = udev_device_get_action(udev_device); if (action) { - if (!strcmp(action, "add")) - device_added(udev_device); - else if (!strcmp(action, "remove")) - device_removed(udev_device); - else if (!strcmp(action, "change")) { + if (!strcmp(action, "add") || !strcmp(action, "change")) { device_removed(udev_device); device_added(udev_device); } + else if (!strcmp(action, "remove")) + device_removed(udev_device); } udev_device_unref(udev_device); } @@ -283,6 +281,9 @@ config_udev_init(void) if (!udev_monitor) return 0; + udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "input", NULL); + udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "tty", NULL); /* For Wacom serial devices */ + if (udev_monitor_enable_receiving(udev_monitor)) { ErrorF("config/udev: failed to bind the udev monitor\n"); return 0; @@ -291,11 +292,20 @@ config_udev_init(void) enumerate = udev_enumerate_new(udev); if (!enumerate) return 0; + + udev_enumerate_add_match_subsystem(enumerate, "input"); + udev_enumerate_add_match_subsystem(enumerate, "tty"); + udev_enumerate_scan_devices(enumerate); devices = udev_enumerate_get_list_entry(enumerate); udev_list_entry_foreach(device, devices) { const char *syspath = udev_list_entry_get_name(device); struct udev_device *udev_device = udev_device_new_from_syspath(udev, syspath); + + /* Device might be gone by the time we try to open it */ + if (!udev_device) + continue; + device_added(udev_device); udev_device_unref(udev_device); } diff --git a/configure.ac b/configure.ac index 4656a83fb..24388259c 100644 --- a/configure.ac +++ b/configure.ac @@ -1187,11 +1187,7 @@ if test "x$XKB_DFLT_RULES" = x; then case $host_os in linux*) dnl doesn't take AutoAddDevices into account, but whatever. - if test "x$CONFIG_HAL" = xyes; then - XKB_DFLT_RULES="evdev" - else - XKB_DFLT_RULES="base" - fi + XKB_DFLT_RULES="evdev" ;; *) XKB_DFLT_RULES="base" diff --git a/dix/main.c b/dix/main.c index 955b7ea9e..16575ceba 100644 --- a/dix/main.c +++ b/dix/main.c @@ -347,7 +347,7 @@ int main(int argc, char *argv[], char *envp[]) if (dispatchException & DE_TERMINATE) { - ddxGiveUp(); + ddxGiveUp(EXIT_NO_ERROR); break; } diff --git a/doc/Xserver-spec.xml b/doc/Xserver-spec.xml index 7d7f9152c..b14e4897e 100644 --- a/doc/Xserver-spec.xml +++ b/doc/Xserver-spec.xml @@ -4680,8 +4680,8 @@ An Example implementation is miPushPixels() in Xserver/mi/mipushpxl.c. Shutdown Procedures
- void AbortDDX() - void ddxGiveUp() + void AbortDDX(enum ExitCode error) + void ddxGiveUp(enum ExitCode error)
Some hardware may require special work to be done before the server exits so that it is not left in an intermediate state. As explained diff --git a/hw/dmx/dmxinit.c b/hw/dmx/dmxinit.c index 74b358244..bc1509b35 100644 --- a/hw/dmx/dmxinit.c +++ b/hw/dmx/dmxinit.c @@ -821,7 +821,7 @@ static void dmxSetDefaultFontPath(char *fp) /** This function is called in Xserver/os/utils.c from \a AbortServer(). * We must ensure that backend and console state is restored in the * event the server shutdown wasn't clean. */ -void AbortDDX(void) +void AbortDDX(enum ExitCode error) { int i; @@ -842,9 +842,9 @@ void ddxBeforeReset(void) /** This function is called in Xserver/dix/main.c from \a main() when * dispatchException & DE_TERMINATE (which is the only way to exit the * main loop without an interruption. */ -void ddxGiveUp(void) +void ddxGiveUp(enum ExitCode error) { - AbortDDX(); + AbortDDX(error); } /** This function is called in Xserver/os/osinit.c from \a OsInit(). */ diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c index f034ce463..8dd039e1d 100644 --- a/hw/kdrive/src/kdrive.c +++ b/hw/kdrive/src/kdrive.c @@ -232,7 +232,7 @@ KdProcessSwitch (void) } void -AbortDDX(void) +AbortDDX(enum ExitCode error) { KdDisableScreens (); if (kdOsFuncs) @@ -249,9 +249,9 @@ AbortDDX(void) } void -ddxGiveUp (void) +ddxGiveUp (enum ExitCode error) { - AbortDDX (); + AbortDDX (error); } Bool kdDumbDriver; diff --git a/hw/vfb/InitOutput.c b/hw/vfb/InitOutput.c index 53f82f9e2..31ed50533 100644 --- a/hw/vfb/InitOutput.c +++ b/hw/vfb/InitOutput.c @@ -150,7 +150,7 @@ vfbBitsPerPixel(int depth) } void -ddxGiveUp(void) +ddxGiveUp(enum ExitCode error) { int i; @@ -201,9 +201,9 @@ ddxGiveUp(void) } void -AbortDDX(void) +AbortDDX(enum ExitCode error) { - ddxGiveUp(); + ddxGiveUp(error); } #ifdef __APPLE__ diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 114bdc3a3..58b30dd68 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -1222,6 +1222,7 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) devs = xnfrealloc(servlayoutp->inputs, (count + 1) * sizeof(InputInfoPtr)); devs[count - 1] = xnfalloc(sizeof(InputInfoRec)); + Pointer.fd = -1; *devs[count - 1] = Pointer; devs[count - 1]->options = xf86addNewOption(devs[count -1]->options, @@ -1267,6 +1268,7 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) devs = xnfrealloc(servlayoutp->inputs, (count + 1) * sizeof(InputInfoPtr)); devs[count - 1] = xnfalloc(sizeof(InputInfoRec)); + Pointer.fd = -1; *devs[count - 1] = Pointer; devs[count - 1]->options = xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL); @@ -1363,6 +1365,7 @@ checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout) devs = xnfrealloc(servlayoutp->inputs, (count + 1) * sizeof(InputInfoPtr)); devs[count - 1] = xnfalloc(sizeof(InputInfoRec)); + Keyboard.fd = -1; *devs[count - 1] = Keyboard; devs[count - 1]->options = xf86addNewOption(devs[count - 1]->options, diff --git a/hw/xfree86/common/xf86Configure.c b/hw/xfree86/common/xf86Configure.c index 975266943..ab0751507 100644 --- a/hw/xfree86/common/xf86Configure.c +++ b/hw/xfree86/common/xf86Configure.c @@ -749,7 +749,7 @@ DoConfigure(void) bail: OsCleanup(TRUE); - AbortDDX(); + AbortDDX(EXIT_ERR_CONFIGURE); fflush(stderr); exit(0); } diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c index 3cdffdb43..f8e6c8b41 100644 --- a/hw/xfree86/common/xf86Helper.c +++ b/hw/xfree86/common/xf86Helper.c @@ -1198,9 +1198,9 @@ xf86LogInit(void) } void -xf86CloseLog(void) +xf86CloseLog(enum ExitCode error) { - LogClose(); + LogClose(error); } diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 15fdbc349..71926f8e7 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -791,6 +791,21 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) NULL); } +static InputInfoPtr +duplicateDevice(InputInfoPtr pInfo) +{ + InputInfoPtr dup = calloc(1, sizeof(InputInfoRec)); + if (dup) { + dup->name = strdup(pInfo->name); + dup->driver = strdup(pInfo->driver); + dup->options = xf86OptionListDuplicate(pInfo->options); + /* type_name is a const string */ + dup->type_name = pInfo->type_name; + dup->fd = -1; + } + return dup; +} + /* * InitInput -- * Initialize all supported input devices. @@ -799,7 +814,7 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) void InitInput(int argc, char **argv) { - InputInfoPtr* pDev; + InputInfoPtr* pInfo; DeviceIntPtr dev; xf86Info.vtRequestsPending = FALSE; @@ -807,14 +822,21 @@ InitInput(int argc, char **argv) mieqInit(); /* Initialize all configured input devices */ - for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) { + for (pInfo = xf86ConfigLayout.inputs; pInfo && *pInfo; pInfo++) { + InputInfoPtr dup; /* Replace obsolete keyboard driver with kbd */ - if (!xf86NameCmp((*pDev)->driver, "keyboard")) { - strcpy((*pDev)->driver, "kbd"); + if (!xf86NameCmp((*pInfo)->driver, "keyboard")) { + strcpy((*pInfo)->driver, "kbd"); } + /* Data passed into xf86NewInputDevice will be freed on shutdown. + * Duplicate from xf86ConfigLayout.inputs, otherwise we don't have any + * xorg.conf input devices in the second generation + */ + dup = duplicateDevice(*pInfo); + /* If one fails, the others will too */ - if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc) + if (xf86NewInputDevice(dup, &dev, TRUE) == BadAlloc) break; } @@ -880,7 +902,7 @@ OsVendorInit(void) */ void -ddxGiveUp(void) +ddxGiveUp(enum ExitCode error) { int i; @@ -907,7 +929,7 @@ ddxGiveUp(void) if (xorgHWOpenConsole) xf86CloseConsole(); - xf86CloseLog(); + xf86CloseLog(error); /* If an unexpected signal was caught, dump a core for debugging */ if (xf86Info.caughtSignal) @@ -924,7 +946,7 @@ ddxGiveUp(void) */ void -AbortDDX(void) +AbortDDX(enum ExitCode error) { int i; @@ -957,7 +979,7 @@ AbortDDX(void) * This is needed for an abnormal server exit, since the normal exit stuff * MUST also be performed (i.e. the vt must be left in a defined state) */ - ddxGiveUp(); + ddxGiveUp(error); } void diff --git a/hw/xfree86/common/xf86Option.c b/hw/xfree86/common/xf86Option.c index 480f38694..a3a836fc1 100644 --- a/hw/xfree86/common/xf86Option.c +++ b/hw/xfree86/common/xf86Option.c @@ -340,7 +340,7 @@ pointer xf86AddNewOption(pointer head, const char *name, const char *val) { /* XXX These should actually be allocated in the parser library. */ - char *tmp = strdup(val); + char *tmp = val ? strdup(val) : NULL; char *tmp_name = strdup(name); return xf86addNewOption(head, tmp_name, tmp); diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 5d91ab367..1fe3d7e0d 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -140,7 +140,7 @@ extern _X_EXPORT pmWait (*xf86PMConfirmEventToOs)(int fd,pmEvent event); /* xf86Helper.c */ extern _X_EXPORT void xf86LogInit(void); -extern _X_EXPORT void xf86CloseLog(void); +extern _X_EXPORT void xf86CloseLog(enum ExitCode error); /* xf86Init.c */ extern _X_EXPORT Bool xf86LoadModules(char **list, pointer *optlist); diff --git a/hw/xfree86/common/xf86ShowOpts.c b/hw/xfree86/common/xf86ShowOpts.c index c0fa80ac7..a8059168d 100644 --- a/hw/xfree86/common/xf86ShowOpts.c +++ b/hw/xfree86/common/xf86ShowOpts.c @@ -124,7 +124,7 @@ void DoShowOptions (void) { } bail: OsCleanup (TRUE); - AbortDDX (); + AbortDDX (EXIT_ERR_DRIVERS); fflush (stderr); exit (0); } diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 26051ad7f..d22fdc8b9 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -844,6 +844,7 @@ xf86NewInputDevice(InputInfoPtr pInfo, DeviceIntPtr *pdev, BOOL enable) { OsReleaseSignals(); xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", pInfo->name); + RemoveDevice(dev, TRUE); rval = BadMatch; goto unwind; } diff --git a/hw/xnest/Init.c b/hw/xnest/Init.c index ea0669a6a..af57518ba 100644 --- a/hw/xnest/Init.c +++ b/hw/xnest/Init.c @@ -114,16 +114,16 @@ CloseInput(void) /* * DDX - specific abort routine. Called by AbortServer(). */ -void AbortDDX(void) +void AbortDDX(enum ExitCode error) { xnestDoFullGeneration = True; xnestCloseDisplay(); } /* Called by GiveUp(). */ -void ddxGiveUp(void) +void ddxGiveUp(enum ExitCode error) { - AbortDDX(); + AbortDDX(error); } #ifdef __APPLE__ diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 73685b0d4..f19d7bf30 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -766,9 +766,9 @@ void ddxUseMsg( void ) * ddxGiveUp -- * Device dependent cleanup. Called by dix before normal server death. */ -void ddxGiveUp( void ) +void ddxGiveUp( enum ExitCode error ) { - ErrorF( "Quitting Xquartz\n" ); + LogClose(error); } @@ -779,7 +779,7 @@ void ddxGiveUp( void ) * are closed. */ _X_NORETURN -void AbortDDX( void ) { +void AbortDDX( enum ExitCode error ) { ErrorF( " AbortDDX\n" ); OsAbort(); } diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c index 22ef8da76..4fe5053b3 100644 --- a/hw/xwin/InitOutput.c +++ b/hw/xwin/InitOutput.c @@ -191,7 +191,7 @@ ddxBeforeReset (void) /* See Porting Layer Definition - p. 57 */ void -ddxGiveUp (void) +ddxGiveUp (enum ExitCode error) { int i; @@ -228,7 +228,7 @@ ddxGiveUp (void) g_pszLogFile = LogInit (g_pszLogFile, NULL); g_fLogInited = TRUE; } - LogClose (); + LogClose (error); /* * At this point we aren't creating any new screens, so @@ -258,12 +258,12 @@ ddxGiveUp (void) /* See Porting Layer Definition - p. 57 */ void -AbortDDX (void) +AbortDDX (enum ExitCode error) { #if CYGDEBUG winDebug ("AbortDDX\n"); #endif - ddxGiveUp (); + ddxGiveUp (error); } #ifdef __CYGWIN__ @@ -901,7 +901,7 @@ ddxUseMsg(void) g_pszLogFile = LogInit (g_pszLogFile, NULL); g_fLogInited = TRUE; } - LogClose (); + LogClose (EXIT_NO_ERROR); /* Notify user where UseMsg text can be found.*/ if (!g_fNoHelpMessageBox) diff --git a/hw/xwin/winerror.c b/hw/xwin/winerror.c index 5e32d090d..0440d13ff 100644 --- a/hw/xwin/winerror.c +++ b/hw/xwin/winerror.c @@ -81,7 +81,7 @@ OsVendorFatalError (void) g_fLogInited = TRUE; g_pszLogFile = LogInit (g_pszLogFile, NULL); } - LogClose (); + LogClose (EXIT_ERR_ABORT); winMessageBoxF ( "A fatal error has occurred and " PROJECT_NAME " will now exit.\n" \ diff --git a/include/os.h b/include/os.h index 506dc5d2a..a553f5783 100644 --- a/include/os.h +++ b/include/os.h @@ -459,8 +459,15 @@ typedef struct { /* stuff for FlushCallback */ extern _X_EXPORT CallbackListPtr FlushCallback; -extern _X_EXPORT void AbortDDX(void); -extern _X_EXPORT void ddxGiveUp(void); +enum ExitCode { + EXIT_NO_ERROR = 0, + EXIT_ERR_ABORT = 1, + EXIT_ERR_CONFIGURE = 2, + EXIT_ERR_DRIVERS = 3, +}; + +extern _X_EXPORT void AbortDDX(enum ExitCode error); +extern _X_EXPORT void ddxGiveUp(enum ExitCode error); extern _X_EXPORT int TimeSinceLastInputEvent(void); /* strcasecmp.c */ @@ -508,7 +515,7 @@ typedef enum { } MessageType; extern _X_EXPORT const char *LogInit(const char *fname, const char *backup); -extern _X_EXPORT void LogClose(void); +extern _X_EXPORT void LogClose(enum ExitCode error); extern _X_EXPORT Bool LogSetParameter(LogParameter param, int value); extern _X_EXPORT void LogVWrite(int verb, const char *f, va_list args) _X_ATTRIBUTE_PRINTF(2,0); extern _X_EXPORT void LogWrite(int verb, const char *f, ...) _X_ATTRIBUTE_PRINTF(2,3); diff --git a/os/log.c b/os/log.c index 4a310e64d..f51976284 100644 --- a/os/log.c +++ b/os/log.c @@ -231,9 +231,11 @@ LogInit(const char *fname, const char *backup) } void -LogClose(void) +LogClose(enum ExitCode error) { if (logFile) { + ErrorF("Server terminated %s (%d). Closing log file.\n", + (error == EXIT_NO_ERROR) ? "successfully" : "with error", error); fclose(logFile); logFile = NULL; } @@ -411,7 +413,7 @@ AbortServer(void) CloseWellKnownConnections(); OsCleanup(TRUE); CloseDownDevices(); - AbortDDX(); + AbortDDX(EXIT_ERR_ABORT); fflush(stderr); if (CoreDump) OsAbort();