summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2012-05-28 09:08:43 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2012-07-04 08:21:11 +1000
commitf4e76a4c53f2abe0bd737485e0b32d6d36425118 (patch)
treeb8eb6aa1cec125b40ceba3466b5fd1f3a0ce4c64 /src
parentac772cde9469c406564433d6d41416fa2279fbf9 (diff)
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 <zdenek.kabelac@gmail.com> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Chase Douglas <chase.douglas@canonical.com> (cherry picked from commit ac5173163d7d1e18d47630a397ece0f26b2568c8)
Diffstat (limited to 'src')
-rw-r--r--src/evdev.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/src/evdev.c b/src/evdev.c
index d7f4492..bd8d9b8 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;
}