From 882e3c2680c339ad7aa0d664e0b0f02b8a05b11d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 18 Jul 2011 21:17:10 +0200 Subject: config: process udev "changed" and "add" events in the same code paths udev gives no guarantee that before each "changed" event for a device there's an "add" event, or that before each "remove" is an "add", or that before each "add" there was no "add" already and so on. Users can trigger these events at any time with "udevadm trigger", and netlink is a lossy transport, hence the events can come in unexpected ordering. With other words: regardless which event is generated, the X server must not choke on it and make the best of it, hence make sure that if we get an "add" event for an existing device we don't add the device a second time. Signed-off-by: Lennart Poettering Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- config/udev.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/config/udev.c b/config/udev.c index 9ac34ee50..5ac52a1d7 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); } -- cgit v1.2.3 From f13de9ca1b7c4dd0dd5c08037c6bd53f88ac30f5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 18 Jul 2011 21:17:49 +0200 Subject: config: limit the kernel subsystems we look for devices in Don't enumerate/monitor all devices of the system (since that can be quite a few), but limit our search to devices from the "input" subsystem, as well as the "tty" subsystem (to cover Wacom tablets). This should make X start up a bit faster and reduce the number of unnecessary wake-ups of the X server. Signed-off-by: Lennart Poettering Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- config/udev.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/config/udev.c b/config/udev.c index 5ac52a1d7..0763cc9a0 100644 --- a/config/udev.c +++ b/config/udev.c @@ -281,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; @@ -289,6 +292,10 @@ 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) { -- cgit v1.2.3 From 6cea28fe4b7a4a22ad270d8c71403db84a9bfb2c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 18 Jul 2011 21:18:27 +0200 Subject: config: don't fail if a device vanished by the time we managed to look at it The nature of hotplug is that a device we enumerated might already be gone by the time we look at it, so don't assume otherwise. Signed-off-by: Lennart Poettering Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- config/udev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/udev.c b/config/udev.c index 0763cc9a0..e7383dc36 100644 --- a/config/udev.c +++ b/config/udev.c @@ -301,6 +301,11 @@ config_udev_init(void) 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); } -- cgit v1.2.3 From 8ffddbcf72170e246826ee0f39f18989a29fa218 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 27 Jun 2011 16:30:28 +1000 Subject: xfree86: Remove devices that failed to enable on startup Devices that succeeded during PreInit and DEVICE_INIT but failed in DEVICE_ON would be deleted through xf86DeleteInput but not removed from the list of input devices (and not turned off). The result was a double free on server shutdown. Fix this by calling RemoveDevice if EnableDevice fails. Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- hw/xfree86/common/xf86Xinput.c | 1 + 1 file changed, 1 insertion(+) 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; } -- cgit v1.2.3 From f0d7e9db28c374a3db359bcb63a7ce79fd84b541 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 4 Jul 2011 14:14:39 +1000 Subject: xfree86: duplicate xorg.conf device information before xf86NewInputDevice xf86ConfigLayout.inputs contains the information from the xorg.conf file. Passing this into xf86NewInputDevice means the device will get cleaned up on exit and the pointers in xf86ConfigLayout.inputs are left dangling. In the second server generation, this results in a server crash. Also, rename pDev to pInfo. pDev is pretty much reserved for DeviceIntPtr types. Reproducible: AutoAddDevices off and xorg.conf input sections, trigger server regeneration. Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- hw/xfree86/common/xf86Init.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 15fdbc349..5347bbfc0 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; } -- cgit v1.2.3 From f2a6735cfc07789cca81852b24a85578f200d83d Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 4 Jul 2011 12:34:32 +1000 Subject: xfree86: NULL option values are technically valid, don't strdup them Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- hw/xfree86/common/xf86Option.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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); -- cgit v1.2.3 From 3798dd379c1ecf325f9907128fb66d20372f6876 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 20 Jul 2011 09:00:18 +1000 Subject: Initialize the fd to -1 for xorg.conf input devices. For hotplugged devices, xf86AllocateInput does that for us but the xorg.conf path is different. Since not all drivers reset the fd during PreInit but may still call close(pInfo->fd) in all cases, this can terminate the logging early. Reproducible: add a wacom driver InputDevice section with no Option Device. Signed-off-by: Peter Hutterer Reviewed-by: Daniel Stone --- hw/xfree86/common/xf86Config.c | 3 +++ 1 file changed, 3 insertions(+) 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, -- cgit v1.2.3 From 01de08c7d2c00eef238adba6665896ea3cd7d511 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Tue, 26 Jul 2011 20:40:38 +0200 Subject: configure: set default xkb rules to evdev on Linux If config/udev was enabled, this would default to base, which means that after regen the devices would get the wrong rules, and hilarity would ensue. It's probably safe to default to evdev unconditionally on Linux by now. Reported-by: Bastian Blank Signed-off-by: Julien Cristau Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- configure.ac | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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" -- cgit v1.2.3 From f51e42f583073bde0bc8131887cb7220636c8855 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 20 Jul 2011 13:09:05 +1000 Subject: Terminate the log with one last message. Instead of just closing the log when everything is done, put one more message in stating that we're actually terminating. Users or scripts that look at the Xorg.log will then know that a) the server has terminated properly and b) why the server terminated (to some degree, given that most real-world errors will be caused by AbortServer()). Acked-by: Gaetan Nadon Reviewed-by: Daniel Stone Tested-by: Jeremy Huddleston Reviewed-by: Jeremy Huddleston Tested-by: Jon TURNEY Reviewed-by: Jon TURNEY Signed-off-by: Peter Hutterer --- dix/main.c | 2 +- doc/Xserver-spec.xml | 4 ++-- hw/dmx/dmxinit.c | 6 +++--- hw/kdrive/src/kdrive.c | 6 +++--- hw/vfb/InitOutput.c | 6 +++--- hw/xfree86/common/xf86Configure.c | 2 +- hw/xfree86/common/xf86Helper.c | 4 ++-- hw/xfree86/common/xf86Init.c | 8 ++++---- hw/xfree86/common/xf86Priv.h | 2 +- hw/xfree86/common/xf86ShowOpts.c | 2 +- hw/xnest/Init.c | 6 +++--- hw/xquartz/darwin.c | 6 +++--- hw/xwin/InitOutput.c | 10 +++++----- hw/xwin/winerror.c | 2 +- include/os.h | 13 ++++++++++--- os/log.c | 6 ++++-- 16 files changed, 47 insertions(+), 38 deletions(-) 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/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 5347bbfc0..71926f8e7 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -902,7 +902,7 @@ OsVendorInit(void) */ void -ddxGiveUp(void) +ddxGiveUp(enum ExitCode error) { int i; @@ -929,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) @@ -946,7 +946,7 @@ ddxGiveUp(void) */ void -AbortDDX(void) +AbortDDX(enum ExitCode error) { int i; @@ -979,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/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/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(); -- cgit v1.2.3