+ int n, fd, pid;
+ struct stat sbuf;
+ char ascii_pid[12];
+
+ if (stat(dev, &sbuf) < 0) {
+ syslog(LOG_ERR, "Can't get device number for %s: %m", dev);
+ return -1;
+ }
+ if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {
+ syslog(LOG_ERR, "Can't lock %s: not a character device", dev);
+ return -1;
+ }
+ sprintf(lock_file, "%s%03d.%03d", LOCK_PREFIX, major(sbuf.st_rdev),
+ minor(sbuf.st_rdev));
+
+ while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
+ if (errno == EEXIST
+ && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {
+ /* Read the lock file to find out who has the device locked */
+ n = read(fd, ascii_pid, 11);
+ if (n <= 0) {
+ syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file);
+ close(fd);
+ } else {
+ ascii_pid[n] = 0;
+ pid = atoi(ascii_pid);
+ if (pid > 0 && kill(pid, 0) == -1 && errno == ESRCH) {
+ /* pid no longer exists - remove the lock file */
+ if (unlink(lock_file) == 0) {
+ close(fd);
+ syslog(LOG_NOTICE, "Removed stale lock on %s (pid %d)",
+ dev, pid);
+ continue;
+ } else
+ syslog(LOG_WARNING, "Couldn't remove stale lock on %s",
+ dev);
+ } else
+ syslog(LOG_NOTICE, "Device %s is locked by pid %d",
+ dev, pid);
+ }
+ close(fd);
+ } else
+ syslog(LOG_ERR, "Can't create lock file %s: %m", lock_file);
+ lock_file[0] = 0;
+ return -1;
+ }
+
+ sprintf(ascii_pid, "%10d\n", getpid());
+ write(fd, ascii_pid, 11);
+
+ close(fd);