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 <[email protected]> Signed-off-by: Peter Hutterer <[email protected]> --- src/evdev.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/evdev.c b/src/evdev.c index 1a1180b..120c65b 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); @@ -1109,8 +1110,7 @@ EvdevReadInput(InputInfoPtr pInfo) EvdevMBEmuFinalize(pInfo); Evdev3BEmuFinalize(pInfo); xf86RemoveEnabledDevice(pInfo); - close(pInfo->fd); - pInfo->fd = -1; + EvdevCloseDevice(pInfo); } else if (errno != EAGAIN) LogMessageVerbSigSafe(X_ERROR, 0, "%s: Read error: %s\n", pInfo->name, strerror(errno)); @@ -1863,8 +1863,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; @@ -1873,10 +1872,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; @@ -2365,17 +2361,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) { @@ -2456,8 +2469,7 @@ EvdevPreInit(InputDriverPtr drv, InputInfoPtr pInfo, int flags) return Success; error: - if (pInfo->fd >= 0) - close(pInfo->fd); + EvdevCloseDevice(pInfo); return rc; } -- 1.7.10.2 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
