[PATCH evdev 3/6] Release mtdev data whenever we close the fd

Peter Hutterer peter.hutterer at who-t.net
Wed Jun 6 18:36:57 PDT 2012


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 at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 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



More information about the xorg-devel mailing list