From ac5173163d7d1e18d47630a397ece0f26b2568c8 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 28 May 2012 09:08:43 +1000 Subject: Release mtdev data whenever we close the fd Add a new EvdevCloseDevice() function to unify this. We used to leak data - PreInit allocates mtdev, but nothing except one error path released it. - each DEVICE_ON re-allocates mtdev but it is never released Reported-by: Zdenek Kabelac Signed-off-by: Peter Hutterer Reviewed-by: Chase Douglas --- src/evdev.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 055bc3f..fb44c37 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -119,6 +119,7 @@ static int EvdevSwitchMode(ClientPtr client, DeviceIntPtr device, int mode); static BOOL EvdevGrabDevice(InputInfoPtr pInfo, int grab, int ungrab); static void EvdevSetCalibration(InputInfoPtr pInfo, int num_calibration, int calibration[4]); static int EvdevOpenDevice(InputInfoPtr pInfo); +static void EvdevCloseDevice(InputInfoPtr pInfo); static void EvdevInitAxesLabels(EvdevPtr pEvdev, int mode, int natoms, Atom *atoms); static void EvdevInitButtonLabels(EvdevPtr pEvdev, int natoms, Atom *atoms); @@ -1108,8 +1109,7 @@ EvdevReadInput(InputInfoPtr pInfo) EvdevMBEmuFinalize(pInfo); Evdev3BEmuFinalize(pInfo); xf86RemoveEnabledDevice(pInfo); - close(pInfo->fd); - pInfo->fd = -1; + EvdevCloseDevice(pInfo); } else if (errno != EAGAIN) { /* We use X_NONE here because it doesn't alloc */ @@ -1866,8 +1866,7 @@ EvdevProc(DeviceIntPtr device, int what) { EvdevGrabDevice(pInfo, 0, 1); xf86RemoveEnabledDevice(pInfo); - close(pInfo->fd); - pInfo->fd = -1; + EvdevCloseDevice(pInfo); } pEvdev->min_maj = 0; pEvdev->flags &= ~EVDEV_INITIALIZED; @@ -1876,10 +1875,7 @@ EvdevProc(DeviceIntPtr device, int what) case DEVICE_CLOSE: xf86IDrvMsg(pInfo, X_INFO, "Close\n"); - if (pInfo->fd != -1) { - close(pInfo->fd); - pInfo->fd = -1; - } + EvdevCloseDevice(pInfo); EvdevFreeMasks(pEvdev); EvdevRemoveDevice(pInfo); pEvdev->min_maj = 0; @@ -2368,17 +2364,34 @@ EvdevOpenDevice(InputInfoPtr pInfo) if (EvdevIsDuplicate(pInfo)) { xf86IDrvMsg(pInfo, X_WARNING, "device file is duplicate. Ignoring.\n"); + EvdevCloseDevice(pInfo); + return BadMatch; + } + + return Success; +} + +static void +EvdevCloseDevice(InputInfoPtr pInfo) +{ + EvdevPtr pEvdev = pInfo->private; + if (pInfo->fd >= 0) + { close(pInfo->fd); + pInfo->fd = -1; + } + #ifdef MULTITOUCH + if (pEvdev->mtdev) + { mtdev_close_delete(pEvdev->mtdev); pEvdev->mtdev = NULL; -#endif - return BadMatch; } +#endif - return Success; } + static void EvdevUnInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) { @@ -2459,8 +2472,7 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) return Success; error: - if (pInfo->fd >= 0) - close(pInfo->fd); + EvdevCloseDevice(pInfo); return rc; } -- cgit v1.2.3