[Pommed-commits] r328 - in trunk: . pommed

Julien Blache jblache at alioth.debian.org
Sat May 12 13:00:13 UTC 2007


Author: jblache
Date: 2007-05-12 13:00:12 +0000 (Sat, 12 May 2007)
New Revision: 328

Modified:
   trunk/ChangeLog
   trunk/pommed/cd_eject.c
Log:
Added umount support to the CD ejection code & slightly rework the code.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-05-06 12:50:21 UTC (rev 327)
+++ trunk/ChangeLog	2007-05-12 13:00:12 UTC (rev 328)
@@ -2,8 +2,8 @@
 --------------------
 
 version 1.5:
+	- pommed: added umount support to the CD ejection code.
 
-
 version 1.4:
 	- pommed: add proper support for the PowerBook5,8 and PowerBook5,9
 	(PMU05 machines); add Geyser keyboard identification, PMU05

Modified: trunk/pommed/cd_eject.c
===================================================================
--- trunk/pommed/cd_eject.c	2007-05-06 12:50:21 UTC (rev 327)
+++ trunk/pommed/cd_eject.c	2007-05-12 13:00:12 UTC (rev 328)
@@ -25,8 +25,11 @@
 #include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <fcntl.h>
 
+#include <errno.h>
+
 #include <syslog.h>
 
 #include <sys/ioctl.h>
@@ -38,6 +41,96 @@
 #include "dbus.h"
 
 
+static char *
+check_mount(char *device)
+{
+  char line[1024];
+  char dev[512];
+  char mpoint[512];
+
+  int ret;
+  FILE *fp;
+
+  fp = fopen("/proc/mounts", "r");
+  if (fp == NULL)
+    {
+      logmsg(LOG_ERR, "Could not open mount table for reading: %s\n", strerror(errno));
+      return NULL;
+    }
+
+  while (fgets(line, sizeof(line), fp) != 0)
+    {
+      ret = sscanf(line, "%511s %511s", dev, mpoint);
+      if (ret < 2)
+	continue;
+
+      if (strcmp(dev, device) == 0)
+	{
+	  fclose(fp);
+	  return strdup(mpoint);
+	}
+    }
+
+  fclose(fp);
+
+  return NULL;
+}
+
+static int
+try_to_unmount(char *device)
+{
+  char *rdev;
+  char *mpoint;
+  int ret;
+
+  /* passing NULL is a GNU extension, recommended by POSIX */
+  rdev = realpath(device, NULL);
+  if (rdev == NULL)
+    return -1;
+
+  mpoint = check_mount(rdev);
+  if (mpoint == NULL)
+    {
+      free(rdev);
+      return 0;
+    }
+
+  logdebug("%s (%s) mounted on %s; attempting to unmount\n", device, rdev, mpoint);
+
+  ret = fork();
+  if (ret == 0) /* exec umount */
+    {
+      /* We need to call umount because mount/umount maintain /etc/mtab ... */
+      execl("/bin/umount", "umount", mpoint, NULL);
+
+      logmsg(LOG_ERR, "Could not execute umount: %s", strerror(errno));
+      exit(1);
+    }
+  else if (ret == -1)
+    {
+      logmsg(LOG_ERR, "Could not fork: %s\n", strerror(errno));
+      free(rdev);
+      free(mpoint);
+      return -1;
+    }
+  else
+    {
+      waitpid(ret, &ret, 0);
+      if ((WIFEXITED(ret) == 0) || (WEXITSTATUS(ret) != 0))
+	{
+	  logmsg(LOG_INFO, "umount failed");
+	  free(rdev);
+	  free(mpoint);
+	  return -1;
+	}
+    }
+
+  free(rdev);
+  free(mpoint);
+  return 0;
+}
+
+
 void
 cd_eject(void)
 {
@@ -50,42 +143,60 @@
   fd = open(eject_cfg.device, O_RDONLY | O_NONBLOCK);
   if (fd < 0)
     {
-      logmsg(LOG_ERR, "Could not open CD/DVD device");
+      logmsg(LOG_ERR, "Could not open CD/DVD device: %s", strerror(errno));
 
       return;
     }
 
   /* Check drive status */
   ret = ioctl(fd, CDROM_DRIVE_STATUS);
+  close(fd);
+
   switch (ret)
     {
-      case CDS_NO_INFO: /* fall through */
+      case CDS_NO_INFO: /* fall through to CDS_DISC_OK */
 	logmsg(LOG_INFO, "Driver does not support CDROM_DRIVE_STATUS, trying to eject anyway");
 
       case CDS_DISC_OK:
-	mbpdbus_send_cd_eject();
-
-	ret = ioctl(fd, CDROMEJECT);
-	if (ret != 0)
-	  logmsg(LOG_ERR, "Eject command failed");
 	break;
 
       case CDS_NO_DISC:
 	logmsg(LOG_INFO, "No disc in CD/DVD drive");
-	break;
+	return;
 
       case CDS_DRIVE_NOT_READY:
 	logmsg(LOG_INFO, "Drive not ready, please retry later");
-	break;
+	return;
 
       case CDS_TRAY_OPEN:
 	logmsg(LOG_INFO, "Drive tray already open");
-	break;
+	return;
 
       default:
-	logmsg(LOG_INFO, "CDROM_DRIVE_STATUS returned %d", ret);
+	logmsg(LOG_INFO, "CDROM_DRIVE_STATUS returned %d (%s)", ret, strerror(errno));
+	return;
     }
 
+  ret = try_to_unmount(eject_cfg.device);
+  if (ret < 0)
+    {
+      logmsg(LOG_ERR, "Could not unmount device");
+      return;
+    }
+
+  mbpdbus_send_cd_eject();
+
+  fd = open(eject_cfg.device, O_RDONLY | O_NONBLOCK);
+  if (fd < 0)
+    {
+      logmsg(LOG_ERR, "Could not open CD/DVD device: %s", strerror(errno));
+      return;
+    }
+
+  ret = ioctl(fd, CDROMEJECT);
+  if (ret != 0)
+    logmsg(LOG_ERR, "Eject command failed: %s", strerror(errno));
+
   close(fd);
 }
 




More information about the Pommed-commits mailing list