chiark / gitweb /
replace "add|change" with "!remove"
[elogind.git] / extras / cdrom_id / cdrom_id.c
index 2380b158a07ece9cb076b3fb82434fd1c9f5b2ff..894a8905749e90c203fcbe41d6a06e09a7a868dc 100644 (file)
@@ -30,6 +30,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <getopt.h>
+#include <time.h>
 #include <scsi/sg.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -112,6 +113,29 @@ static unsigned long long int cd_media_session_last_offset;
 #define ASC(errcode)   (((errcode) >> 8) & 0xFF)
 #define ASCQ(errcode)  ((errcode) & 0xFF)
 
+static int is_mounted(const char *device)
+{
+       struct stat statbuf;
+       FILE *fp;
+       int maj, min;
+       int mounted = 0;
+
+       if (stat(device, &statbuf) < 0)
+               return -ENODEV;
+
+       fp = fopen("/proc/self/mountinfo", "r");
+       if (fp == NULL)
+               return -ENOSYS;
+       while (fscanf(fp, "%*s %*s %i:%i %*[^\n]", &maj, &min) == 2) {
+               if (makedev(maj, min) == statbuf.st_rdev) {
+                       mounted = 1;
+                       break;
+               }
+       }
+       fclose(fp);
+       return mounted;
+}
+
 static void info_scsi_cmd_err(struct udev *udev, char *cmd, int err)
 {
        if (err == -1) {
@@ -523,6 +547,7 @@ int main(int argc, char *argv[])
        const char *node = NULL;
        int export = 0;
        int fd = -1;
+       int cnt;
        int rc = 0;
 
        udev = udev_new();
@@ -568,7 +593,17 @@ int main(int argc, char *argv[])
                goto exit;
        }
 
-       fd = open(node, O_RDONLY | O_NONBLOCK);
+       srand((unsigned int)getpid());
+       for (cnt = 20; cnt > 0; cnt--) {
+               struct timespec duration;
+
+               fd = open(node, O_RDONLY|O_NONBLOCK|(is_mounted(node) ? 0 : O_EXCL));
+               if (fd >= 0 || errno != EBUSY)
+                       break;
+               duration.tv_sec = 0;
+               duration.tv_nsec = (100 * 1000 * 1000) + (rand() % 100 * 1000 * 1000);
+               nanosleep(&duration, NULL);
+       }
        if (fd < 0) {
                info(udev, "unable to open '%s'\n", node);
                fprintf(stderr, "unable to open '%s'\n", node);