Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37894751
en ru br
ALT Linux repos
S:1.0.3-alt3.2
5.0: 1.0.3-alt1.1
4.1: 1.0.3-alt1
4.0: 1.0.3-alt1
3.0: 1.0.1-alt3

Group :: System/Libraries
RPM: lockdev

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: lockdev-1.0.3-alt3.1.1.1.patch
Download


 .gear/rules                                        |   2 +
 .../tags/0a5aab8b72458317728f51c413e32511d3ff4fe8  |  13 ++
 .gear/tags/list                                    |   1 +
 LockDev/LockDev.pm                                 |  27 +--
 LockDev/LockDev.xs                                 |  29 ---
 Makefile                                           |  19 +-
 docs/lockdev.3                                     |   6 +-
 lockdev.spec                                       | 238 +++++++++++++++++++++
 src/baudboy.h                                      | 136 ++++++++++++
 src/lockdev.c                                      | 103 ++++++---
 src/lockdev.h                                      |   4 +
 src/sample.c                                       |  64 ++++--
 12 files changed, 527 insertions(+), 115 deletions(-)
diff --git a/.gear/rules b/.gear/rules
new file mode 100644
index 0000000..4fcfd99
--- /dev/null
+++ b/.gear/rules
@@ -0,0 +1,2 @@
+tar: @version@:.
+diff: @version@:. .
diff --git a/.gear/tags/0a5aab8b72458317728f51c413e32511d3ff4fe8 b/.gear/tags/0a5aab8b72458317728f51c413e32511d3ff4fe8
new file mode 100644
index 0000000..18120fd
--- /dev/null
+++ b/.gear/tags/0a5aab8b72458317728f51c413e32511d3ff4fe8
@@ -0,0 +1,13 @@
+object 6b1c500d100c19384ac44fe167507561c47ea34a
+type commit
+tag 1.0.3
+tagger Alexey Tourbin <at@altlinux.ru> 1169642228 +0300
+
+1.0.3
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.4.6 (GNU/Linux)
+
+iD8DBQBFt1L2fBKgtDjnu0YRApJ3AKCQnKwO8K6kwN8PMCn77Tjfa5B86gCfS9iS
+feIEBp8y2jIrM2wxF67AhH4=
+=/mxL
+-----END PGP SIGNATURE-----
diff --git a/.gear/tags/list b/.gear/tags/list
new file mode 100644
index 0000000..27ee992
--- /dev/null
+++ b/.gear/tags/list
@@ -0,0 +1 @@
+0a5aab8b72458317728f51c413e32511d3ff4fe8 1.0.3
diff --git a/LockDev/LockDev.pm b/LockDev/LockDev.pm
index 65f7ef8..eac3a53 100644
--- a/LockDev/LockDev.pm
+++ b/LockDev/LockDev.pm
@@ -19,36 +19,11 @@ require DynaLoader;
 );
 $VERSION = '1.0';
 
-sub AUTOLOAD {
-    # This AUTOLOAD is used to 'autoload' constants from the constant()
-    # XS function.  If a constant is not found then control is passed
-    # to the AUTOLOAD in AutoLoader.
-
-    my $constname;
-    ($constname = $AUTOLOAD) =~ s/.*:://;
-    my $val = constant($constname, @_ ? $_[0] : 0);
-    if ($! != 0) {
-	if ($! =~ /Invalid/) {
-	    $AutoLoader::AUTOLOAD = $AUTOLOAD;
-	    goto &AutoLoader::AUTOLOAD;
-	}
-	else {
-		croak "Your vendor has not defined LockDev macro $constname";
-	}
-    }
-    eval "sub $AUTOLOAD { $val }";
-    goto &$AUTOLOAD;
-}
-
 bootstrap LockDev $VERSION;
 
-# Preloaded methods go here.
-
-# Autoload methods go after =cut, and are processed by the autosplit program.
-
 1;
+
 __END__
-# Below is the stub of documentation for your module. You better edit it!
 
 =head1 NAME
 
diff --git a/LockDev/LockDev.xs b/LockDev/LockDev.xs
index b6efd65..b95cc48 100644
--- a/LockDev/LockDev.xs
+++ b/LockDev/LockDev.xs
@@ -10,39 +10,10 @@ extern "C" {
 
 #include "lockdev.h"
 
-static int
-not_here(s)
-char *s;
-{
-    croak("%s not implemented on this architecture", s);
-    return -1;
-}
-
-static double
-constant(name, arg)
-char *name;
-int arg;
-{
-    errno = 0;
-    switch (*name) {
-    }
-    errno = EINVAL;
-    return 0;
-
-not_there:
-    errno = ENOENT;
-    return 0;
-}
-
 
 MODULE = LockDev		PACKAGE = LockDev		
 
 
-double
-constant(name,arg)
-	char *		name
-	int		arg
-
 pid_t
 dev_testlock ( devname)
 	const char * devname;
diff --git a/Makefile b/Makefile
index e27dcbd..2731578 100644
--- a/Makefile
+++ b/Makefile
@@ -6,6 +6,8 @@ pkgname = lockdev
 objs	= src/lockdev.o
 shobjs	= src/lockdev.z
 
+lockdev	= src/sample.c
+
 
 VER	= $(shell expr `pwd` : '.*-\([0-9.]*\)')
 MVER	= ${shell expr `pwd` : '.*-\([0-9]*\).[0-9]*'}
@@ -18,17 +20,18 @@ soname	= ${libname}.so.${MVER}
 basedir	= /usr/local
 srcdir=.
 
+sbindir	= ${basedir}/sbin
 libdir	= ${basedir}/lib
 incdir	= ${basedir}/include
 mandir	= ${basedir}/share/man
 
 CC	= gcc
-LCFLAGS	= -g -O2 -fPIC -Wall -pipe -D_REENTRANT 
-CFLAGS	= -g
+CFLAGS	= -g -O2 -Wall -pipe
+LCFLAGS	= ${CFLAGS} -fPIC -D_REENTRANT
 LDLIBS	= -llockdev
 
 .PHONY: shared static perl-lib
-ALL:	shared static perl-lib
+ALL:	shared static lockdev perl-lib
 
 static ${static}:       ${objs}
 	$(AR) $(ARFLAGS) ${static} $^
@@ -39,6 +42,11 @@ shared ${shared}:	${shobjs}
 src/lockdev.z: src/lockdev.c
 	${CC} ${CFLAGS} -c -fPIC -o $@ $?
 
+lockdev.o: ${lockdev}
+	${CC} ${CFLAGS} -I./src -o $@ -c $^
+
+lockdev: lockdev.o ${static}
+	${CC} -o $@ $^
 
 perl-lib:	static
 	cd LockDev && perl Makefile.PL INSTALLDIRS=vendor
@@ -54,6 +62,7 @@ install_dev:	${static} src/lockdev.h
 	install -m755 -d	${incdir}
 	install -m644 src/lockdev.h	${incdir}
 	install -m644 src/ttylock.h	${incdir}
+	install -m644 src/baudboy.h	${incdir}
 
 install_debug:	${static} ${shared}
 	install -m755 -d	${libdir}/debug
@@ -71,7 +80,9 @@ install_doc:	docs/lockdev.3
 
 install_run:	${shared}
 	install -m755 -d	${libdir}
-	install -m644 ${shared}	${libdir}
+	install -m755 ${shared}	${libdir}
+	install -m755 -d	${sbindir}
+	install -m755 lockdev	${sbindir}
 
 .PHONY: clean distclean perl-clean mostyclean 
 perl-clean:	clean
diff --git a/docs/lockdev.3 b/docs/lockdev.3
index a240227..8d7cefc 100644
--- a/docs/lockdev.3
+++ b/docs/lockdev.3
@@ -17,7 +17,7 @@ lockdev, liblockdev, dev_testlock, dev_lock, dev_relock, dev_unlock \- manage de
 The
 .B lockdev
 functions act on device locks normally located in 
-.B /var/lock .
+.B /var/lock/serial .
 The lock is acquired creating a pair of files hardlinked between them
 and named after the device name (as mandated by FSSTND) and the device's
 major and minor numbers (as in SVr4 locks). This permits to circumvent a
@@ -137,9 +137,9 @@ which installs a shared library built with all
 debugging options (and the -DDEBUG flag) into /usr/lib/debug .
 
 .SH FILES
-/var/lock/LCK..<device>
+/var/lock/serial/LCK..<device>
 .br
-/var/lock/LCK.<major>.<minor>
+/var/lock/serial/LCK.<major>.<minor>
 .br
 /usr/lib/liblockdev.so.1
 .br
diff --git a/lockdev.spec b/lockdev.spec
new file mode 100644
index 0000000..b326d69
--- /dev/null
+++ b/lockdev.spec
@@ -0,0 +1,238 @@
+Name: lockdev
+Version: 1.0.3
+Release: alt3.1.1.1
+
+Summary: A library and a command-line tool for locking devices
+License: LGPL
+Group: System/Libraries
+
+URL: http://packages.debian.org/unstable/source/lockdev
+Source: %name-%version.tar
+Patch: %name-%version-%release.patch
+
+Requires: lib%name = %version-%release
+Requires: /var/lock/serial
+
+# Automatically added by buildreq on Mon Oct 17 2011
+BuildRequires: perl-devel
+
+%description
+The lockdev library provides a reliable way to put an exclusive lock
+on devices using both FSSTND and SVr4 methods.
+
+%package -n lib%name
+Summary: A library for locking devices
+Group: System/Libraries
+
+%description -n lib%name
+The lockdev library provides a reliable way to put an exclusive lock
+on devices using both FSSTND and SVr4 methods.
+
+%package -n lib%name-devel
+Summary: Header files for the %name library
+Group: Development/C
+Requires: lib%name = %version-%release
+
+%description -n lib%name-devel
+The lockdev library provides a reliable way to put an exclusive lock
+on devices using both FSSTND and SVr4 methods.
+
+%package -n lib%name-devel-static
+Summary: Static %name library
+Group: Development/C
+Requires: lib%name = %version-%release
+
+%description -n lib%name-devel-static
+The lockdev library provides a reliable way to put an exclusive lock
+on devices using both FSSTND and SVr4 methods.
+
+%package -n perl-LockDev
+Summary: Perl interface for the %name library
+Group: Development/Perl
+Requires: lib%name = %version-%release
+Provides: %name-perl = %version
+Obsoletes: %name-perl < %version
+
+%description -n perl-LockDev
+The lockdev library provides a reliable way to put an exclusive lock
+on devices using both FSSTND and SVr4 methods.
+
+%prep
+%setup -q
+%patch -p1
+
+%build
+export LD_LIBRARY_PATH=$PWD
+CFLAGS="%optflags -D_GNU_SOURCE -D_REENTRANT -I$PWD/src -Werror"
+LDFLAGS="-L$PWD -l%name"
+
+%define soname lib%name.so.1
+gcc $CFLAGS %optflags_shared src/%name.c -shared -Wl,-soname=%soname,-z,defs -o %soname
+ln -s %soname lib%name.so
+
+%if_enabled static
+gcc $CFLAGS -c src/%name.c -o src/%name-a.o
+ar rcu lib%name.a src/%name-a.o
+ranlib lib%name.a
+%endif
+
+gcc $CFLAGS src/sample.c -o %name $LDFLAGS
+
+cd LockDev
+%perl_vendor_build MYEXTLIB="$LDFLAGS"
+
+%install
+mkdir -p %buildroot%_libdir/
+cp -av lib%name.so* %buildroot%_libdir/
+
+%if_enabled static
+cp -av lib%name.a %buildroot%_libdir/
+%endif
+
+mkdir -p %buildroot%_sbindir/
+cp -av %name %buildroot%_sbindir/
+
+mkdir -p %buildroot%_includedir/
+cp -av src/*.h %buildroot%_includedir/
+
+mkdir -p %buildroot%_man3dir/
+cp -av docs/%name.3 %buildroot%_man3dir/
+
+cd LockDev
+%perl_vendor_install
+
+%files
+%attr(2711,root,uucp) %_sbindir/%name
+
+%files -n perl-LockDev
+%perl_vendor_archlib/LockDev*
+%perl_vendor_autolib/LockDev*
+
+%files -n lib%name
+%_libdir/%soname
+
+%files -n lib%name-devel
+%_libdir/lib%name.so
+%_includedir/*.h
+%_man3dir/%name.*
+
+%if_enabled static
+%files -n lib%name-devel-static
+%_libdir/lib%name.a
+%endif
+
+%changelog
+* Fri Feb 03 2017 Igor Vlasenko <viy@altlinux.ru> 1.0.3-alt3.1.1.1
+- rebuild with new perl 5.24.1
+
+* Wed Nov 25 2015 Igor Vlasenko <viy@altlinux.ru> 1.0.3-alt3.1.1
+- rebuild with new perl 5.22.0
+
+* Tue Dec 09 2014 Igor Vlasenko <viy@altlinux.ru> 1.0.3-alt3.1
+- rebuild with new perl 5.20.1
+
+* Fri Aug 30 2013 Vladimir Lettiev <crux@altlinux.ru> 1.0.3-alt3
+- built for perl 5.18
+
+* Tue Sep 04 2012 Vladimir Lettiev <crux@altlinux.ru> 1.0.3-alt2
+- rebuilt for perl-5.16
+
+* Mon Oct 17 2011 Alexey Tourbin <at@altlinux.ru> 1.0.3-alt1.3
+- rebuilt for perl-5.14
+
+* Fri Nov 05 2010 Vladimir Lettiev <crux@altlinux.ru> 1.0.3-alt1.2
+- rebuilt with perl 5.12
+
+* Sat Dec 13 2008 Dmitriy Khanzhin <jinn@altlinux.ru> 1.0.3-alt1.1
+- built without -Werror
+- fixed URL
+- removed obsolete post{,un}_ldconfig calls
+
+* Thu Mar 01 2007 Alexey Tourbin <at@altlinux.ru> 1.0.3-alt1
+- 1.0.1 -> 1.0.3
+- imported into git and adapted for gear
+- renamed lockdev-perl package to perl-LockDev
+- fixed warnings emitted by new gcc compiler
+- further cleaned up the code (closes #10956 baudboy.h problem)
+
+* Fri Mar 04 2005 Alexey Tourbin <at@altlinux.ru> 1.0.1-alt3
+- rh-pidexists.patch: fix kill/EPERM behaviour (don't unlock files
+  when device is locked by process with different UID)
+- rh-subdir.patch: fix errs on /dev/input/ttyACM0 (3-component pathname)
+- conditionally packaged lib%name-devel-static 
+- perl LockDev(3) manpage not packaged (use perldoc)
+
+* Tue Nov 11 2003 Alexey Tourbin <at@altlinux.ru> 1.0.1-alt2
+- eliminated text relocations in shared library
+- warnings fixed, built with -Werror
+
+* Thu Oct 30 2003 Alexey Tourbin <at@altlinux.ru> 1.0.1-alt1
+- 1.0.1
+- cli.patch and checkname.patch from RH
+- abandon makefiles, custom build with direct commands
+- %name-perl packaged, lib%name-devel-static not packaged
+
+* Wed Oct 23 2002 Konstantin Volckov <goldhead@altlinux.ru> 1.0.0-alt1
+- First build for Sisyphus
+
+* Fri Jun 21 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Wed Jun  5 2002 Jeff Johnson <jbj@redhat.com> 1.0.0-19
+- fix: don't ignore signals, use default behavior instead (#63468).
+
+* Thu May 23 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Mon Feb 25 2002 Nalin Dahyabhai <nalin@redhat.com> 1.0.0-16
+- include liblockdev.so so that programs can link to a shared liblockdev
+- fix shared library version numbers
+
+* Wed Jan 09 2002 Tim Powers <timp@redhat.com>
+- automated rebuild
+
+* Thu Nov 29 2001 Trond Eivind Glomsrød <teg@redhat.com> 1.0.0-16
+- Rebuilt
+
+* Fri Oct 26 2001 Trond Eivind Glomsrød <teg@redhat.com> 1.0.0-15
+- Add copyright/license info to baudboy.h (#54321)
+
+* Tue Sep  4 2001 Jeff Johnson <jbj@redhat.com>
+- swap egid and gid for lockdev's access(2) device check (#52029).
+
+* Tue Aug 28 2001 Jeff Johnson <jbj@redhat.com>
+- typo in include file (#52704).
+- map specific errno's into status for return from helper.
+
+* Tue Aug 14 2001 Jeff Johnson <jbj@redhat.com>
+- set exit status correctly.
+
+* Thu Aug  9 2001 Bill Nottingham <notting@redhat.com>
+- check that we can open the device r/w before locking
+- fix calling lockdev without any arguments
+- fix waitpid() call in baudboy.h
+- use umask(002), not umask(0)
+
+* Wed Aug  8 2001 Bill Nottingham <notting@redhat.com>
+- add lock group here, own /var/lock as well
+
+* Sun Aug  5 2001 Jeff Johnson <jbj@redhat.com>
+- include setgid helper binary and baudboy.h.
+
+* Mon Jun 18 2001 Trond Eivind Glomsrød <teg@redhat.com>
+- Make the -devel depend on the main package
+
+* Sun Aug 06 2000 Trond Eivind Glomsrød <teg@redhat.com>
+- rebuild
+
+* Wed Jul 12 2000 Prospector <bugzilla@redhat.com>
+- automatic rebuild
+
+* Sat Jun 17 2000 Bill Nottingham <notting@redhat.com>
+- add %%defattr for -devel
+
+* Sat Jun 10 2000 Trond Eivind Glomsrød <teg@redhat.com>
+- use %%{_mandir}
+
+* Thu May 04 2000 Trond Eivind Glomsrød <teg@redhat.com>
+- first build
diff --git a/src/baudboy.h b/src/baudboy.h
new file mode 100644
index 0000000..bf95526
--- /dev/null
+++ b/src/baudboy.h
@@ -0,0 +1,136 @@
+/* Copyright (C) 2001 Red Hat, Inc.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License
+   as published by the Free Software Foundation; either version 2 of
+   the License, or (at your option) any later version.
+
+   It is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General
+   Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this software; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+
+#ifndef _BAUDBOY_H_
+#define _BAUDBOY_H_
+
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#define	LOCKDEV_PATH	"/usr/sbin/lockdev"
+
+static inline int _lockdev_run(const char * argv[])
+{
+    pid_t child;
+    int status;
+    void (*osig) (int) = signal(SIGCHLD, SIG_DFL);
+    int rc;
+
+    if (!(child = fork())) {
+	int fd;
+        /* these have to be open to something */
+	if ((fd = open("/dev/null", O_RDWR)) < 0)
+	    exit(-1);
+	dup2(fd, 0);
+	dup2(fd, 1);
+	dup2(fd, 2);
+	close(fd);
+	/* Swap egid and gid for lockdev's access(2) device check. */
+	setregid(getegid(), getgid());
+	execv(argv[0], (char *const *)argv);
+	exit(-1);
+    }
+
+    rc = (int) waitpid(child, &status, 0);
+    signal(SIGCHLD, osig);
+    if (rc == child && WIFEXITED(status)) {
+	/*
+	 * Exit		dev_lock	dev_unlock	dev_testlock
+	 *	  0	OK		OK		not locked
+	 *	  1	locked other	locked other	locked
+	 *	  2	EACCES
+	 *	  3	EROFS
+	 *	  4	EFAULT
+	 *	  5	EINVAL
+	 *	  6	ENAMETOOLONG
+	 *	  7	ENOENT
+	 *	  8	ENOTDIR
+	 *	  9	ENOMEM
+	 *	 10	ELOOP
+	 *	 11	EIO
+	 *	255	error		error		error
+	 */
+	rc = WEXITSTATUS(status);
+	switch(rc) {
+	case  0:	rc = 0;		break;
+	default:
+	case  1:	rc = -EPERM;	break;
+	case  2:	rc = -EACCES;	break;
+	case  3:	rc = -EROFS;	break;
+	case  4:	rc = -EFAULT;	break;
+	case  5:	rc = -EINVAL;	break;
+	case  6:	rc = -ENAMETOOLONG;	break;
+	case  7:	rc = -ENOENT;	break;
+	case  8:	rc = -ENOTDIR;	break;
+	case  9:	rc = -ENOMEM;	break;
+	case 10:	rc = -ELOOP;	break;
+	case 11:	rc = -EIO;	break;
+	}
+    } else if (rc == -1)
+	rc = -errno;
+    else
+	rc = -ECHILD;
+
+    return rc;
+
+}
+
+static inline int ttylock(const char * devname)
+{
+    const char * argv[] = { LOCKDEV_PATH, "-l", NULL, NULL};
+    argv[2] = devname;
+    return _lockdev_run(argv);
+}
+
+static inline int ttyunlock(const char * devname)
+{
+    const char * argv[] = { LOCKDEV_PATH, "-u", NULL, NULL};
+    argv[2] = devname;
+    return _lockdev_run(argv);
+}
+
+static inline int ttylocked(const char * devname)
+{
+    const char * argv[] = { LOCKDEV_PATH, NULL, NULL};
+    argv[1] = devname;
+    return _lockdev_run(argv);
+}
+
+static inline int ttywait(const char * devname)
+{
+    int rc;
+    while((rc = ttylocked(devname)) == 0)
+	sleep(1);
+    return rc;
+}
+
+#ifdef	__cplusplus
+};
+#endif
+
+#endif /* _BAUDBOY_H_ */
diff --git a/src/lockdev.c b/src/lockdev.c
index 8f28002..e7d70d1 100644
--- a/src/lockdev.c
+++ b/src/lockdev.c
@@ -111,12 +111,12 @@
 #include <stdlib.h>
 #include <paths.h>
 #ifndef _PATH_LOCK
-#  define LOCK_PATH	"/var/lock"
+#  define LOCK_PATH	"/var/lock/serial"
 #else
 #  define LOCK_PATH	_PATH_LOCK
 #endif
 #ifndef _PATH_DEV
-#  define DEV_PATH	"/dev"
+#  define DEV_PATH	"/dev/"
 #else
 #  define DEV_PATH	_PATH_DEV
 #endif
@@ -141,14 +141,16 @@
 static inline	int	_dl_filename_0	( char * name, const pid_t pid);
 static inline	int	_dl_filename_1	( char * name, const struct stat * st);
 static inline	int	_dl_filename_2	( char * name, const char * dev);
+#if DEBUG
 static		void	_dl_sig_handler	( int sig);
+#endif
 static		int	_dl_get_semaphore	( int flag);
 static		int	_dl_unlock_semaphore	( int value);
 static inline	int	_dl_lock_semaphore	( void);
 static inline	int	_dl_block_semaphore	( void);
 static		pid_t	_dl_check_lock	( const char * lockname);
 static		char *	_dl_check_devname	( const char * devname);
-
+static inline	int _dl_pid_exists	( pid_t pid );
 
 #define	SEMAPHORE	"LOCKDEV"
 #define	close_n_return( v)	return( _dl_unlock_semaphore( v))
@@ -177,6 +179,19 @@ liblockdev_reset_debug (void)
 	liblockdev_debug = 0;
 }
 
+static pid_t dev_pid = 0;
+
+pid_t dev_getpid(void)
+{
+    return (dev_pid ? dev_pid : getpid());
+}
+
+pid_t dev_setpid(pid_t newpid)
+{
+    pid_t oldpid = dev_pid;
+    dev_pid = newpid;
+    return oldpid;
+}
 
 /*
  * for internal use *
@@ -229,11 +244,12 @@ _dl_filename_2 (char       *name,
 	int l, i;
 	_debug( 3, "_dl_filename_2 (dev=%s)\n", dev);
 	/* lockfile of type /var/lock/LCK..ttyS2 */
-	l = sprintf( name, "%s/LCK..%s", LOCK_PATH, dev);
+	l = snprintf( name, MAXPATHLEN+1, "%s/LCK..%s", LOCK_PATH, dev);
 	_debug( 2, "_dl_filename_2 () -> len=%d, name=%s<\n", l, name);
+	/* replace '/' by '_' for /dev sub-dirs (like pppd does it) */
 	for (i=strlen(LOCK_PATH)+1; name[i] != '\0'; ++i) {
 		if (name[i] == '/')
-			name[i] = ':';
+			name[i] = '_';
 	}
 	return l;
 }
@@ -243,23 +259,23 @@ _dl_filename_2 (char       *name,
 #endif
 
 /* handler for signals */
+#if DEBUG
 static void
 _dl_sig_handler (int sig)
 {
 	signal( sig, _dl_sig_handler);
 	switch( sig ) {
-#if DEBUG
 	case SIGUSR1:
 		liblockdev_debug++;
 		break;
 	case SIGUSR2:
 		liblockdev_debug = 0;
 		break;
-#endif
 	default:
 		break;
 	}
 }
+#endif
 
 /* holds the file descriptor of the lock between the various *_semaphore function calls.
  * its positive conten doesn't tells that we lock the file.
@@ -381,7 +397,7 @@ _dl_check_lock(const char *lockname)
 	/* checks content's format */
 	if ( j == 1 ) {
 		/* checks process existence */
-		if ( ( kill( pid_read, 0) == 0 ) || (errno == EPERM) ) {
+		if ( _dl_pid_exists( pid_read)) {
 			_debug( 2, "_dl_check_lock() locked by %d\n", (int)pid_read);
 			return pid_read;
 		}
@@ -423,18 +439,19 @@ _dl_check_lock(const char *lockname)
 		 * maybe also this sprintf should be added to the
 		 * conditional part, as the others
 		 */
-		sprintf( tpname, "%s/.%d", LOCK_PATH, (int)getpid());
+		sprintf( tpname, "%s/.%d", LOCK_PATH, (int)dev_getpid());
 		unlink( tpname);	/* in case there was */
 		rename( lockname, tpname);
 		if ( ! (fd=fopen( tpname, "r")) ) {
 			return -1;
 		}
-		fscanf( fd, "%d", &pid2);
-		if ( pid2 && (pid2 != pid_read) && ( kill( pid2, 0) == 0 )) {
+		j = fscanf( fd, "%d", &pid2);
+		if ((j == 1) && pid2 && (pid2 != pid_read) && ( _dl_pid_exists( pid2))) {
 			/* lock file was changed! let us quickly
 			 * put it back again
 			 */
-			link( tpname, lockname);
+			if (link( tpname, lockname))
+				;
 			/* could fail, meaning that there is a fourth
 			 * process involved which now owns the lock, but
 			 * it is possible that the third process, who
@@ -467,10 +484,11 @@ _dl_check_devname (const char *devname)
 	 * maybe we should check it and do something if not?
 	 */
 	p = devname;	/* only a filename */
+	p += strspn(p, " \t\r\n\v\f\a");        /* skip leading whitespace */
 	/* If the device is located under /dev/, strip off /dev. */
 	_debug( 3, "_dl_check_devname(%s) strip name = %s\n", devname, DEV_PATH);
-        if (strncmp(DEV_PATH, p, strlen(DEV_PATH)) == 0) {
-		p += 5;
+        if (strncmp(DEV_PATH, p, sizeof(DEV_PATH) - 1) == 0) {
+		p += sizeof(DEV_PATH) - 1; /* sizeof also counts trailing '\0' */
 		_debug( 3, "_dl_check_devname(%s) stripped name = %s\n", devname, p);
 	} else {
 		/* Otherwise, strip off everything but the device name. */
@@ -488,6 +506,18 @@ _dl_check_devname (const char *devname)
 	return strcpy( m, p);
 }
 
+/* for internal use */
+/* correctly check if a process with a given pid exists */
+static inline int
+_dl_pid_exists( pid)
+	pid_t pid;
+{
+	if ( !kill( pid, 0))
+		return 1;
+	if ( errno == ESRCH)
+		return 0;
+	return 1;
+}
 
 /* exported by the interface file lockdev.h */
 /* ZERO means that the device wasn't locked, but could have been locked later */
@@ -512,15 +542,14 @@ dev_testlock(const char *devname)
 	_debug( 3, "dev_testlock(%s)\n", devname);
 	if ( ! (p=_dl_check_devname( devname)) )
 	 	close_n_return( -1);
-	strcpy( device, DEV_PATH);
-	strcat( device, p);	/* now device has a copy of the pathname */
+	snprintf(device, sizeof(device), "%s%s", DEV_PATH, p);
 	_debug( 2, "dev_testlock() device = %s\n", device);
 
 	/* check the device name for existence and retrieve the major
 	 * and minor numbers
 	 */
 	if ( stat( device, &statbuf) == -1 ) {
-		close_n_return( -1);
+		close_n_return(-errno);
 	}
 
 	/* first check for the FSSTND-1.2 lock, get the pid of the
@@ -585,22 +614,24 @@ dev_lock (const char *devname)
 #endif /* DEBUG */
 	_debug( 3, "dev_lock(%s)\n", devname);
 	if (oldmask == -1 )
-		oldmask = umask( 0);	/* give full permissions to files created */
+		oldmask = umask( 002);	/* apply o-w to files created */
 	if ( ! (p=_dl_check_devname( devname)) )
 	 	close_n_return( -1);
-	strcpy( device, DEV_PATH);
-	strcat( device, p);	/* now device has a copy of the pathname */
+	snprintf(device, sizeof(device), "%s%s", DEV_PATH, p);
 	_debug( 2, "dev_lock() device = %s\n", device);
 
 	/* check the device name for existence and retrieve the major
 	 * and minor numbers
 	 */
 	if ( stat( device, &statbuf) == -1 ) {
-		close_n_return( -1);
+		close_n_return(-errno);
+	}
+	if ( access( device, W_OK ) == -1 ) {
+		close_n_return(-errno);
 	}
 
 	/* now get our own pid */
-	our_pid = getpid();
+	our_pid = dev_getpid();
 	_debug( 2, "dev_lock() our own pid = %d\n", (int)our_pid);
 
 	/* We will use this algorithm:
@@ -641,8 +672,9 @@ dev_lock (const char *devname)
 	_dl_filename_1( lock1, &statbuf);
 	while ( ! (pid=_dl_check_lock( lock1)) ) {
 		if (( link( lock0, lock1) == -1 ) && ( errno != EEXIST )) {
+			int rc = -errno;
 			unlink( lock0);
-			close_n_return( -1);
+			close_n_return(rc);
 		}
 	}
 	if ( pid != our_pid ) {
@@ -659,9 +691,10 @@ dev_lock (const char *devname)
 	/* lockfile of type /var/lock/LCK..ttyS2 */
 	while ( ! (pid=_dl_check_lock( lock2)) ) {
 		if (( link( lock0, lock2) == -1 ) && ( errno != EEXIST )) {
+			int rc = -errno;
 			unlink( lock0);
 			unlink( lock1);
-			close_n_return( -1);
+			close_n_return(rc);
 		}
 	}
 	if ( pid != our_pid ) {
@@ -740,22 +773,24 @@ dev_relock (const char  *devname,
 #endif /* DEBUG */
 	_debug( 3, "dev_relock(%s, %d)\n", devname, (int)old_pid);
 	if (oldmask == -1 )
-		oldmask = umask( 0);	/* give full permissions to files created */
+		oldmask = umask( 002);	/* apply o-w to files created */
 	if ( ! (p=_dl_check_devname( devname)) )
 	 	close_n_return( -1);
-	strcpy( device, DEV_PATH);
-	strcat( device, p);	/* now device has a copy of the pathname */
+	snprintf(device, sizeof(device), "%s%s", DEV_PATH, p);
 	_debug( 2, "dev_relock() device = %s\n", device);
 
 	/* check the device name for existence and retrieve the major
 	 * and minor numbers
 	 */
 	if ( stat( device, &statbuf) == -1 ) {
-		close_n_return( -1);
+		close_n_return(-errno);
+	}
+	if ( access( device, W_OK ) == -1 ) {
+		close_n_return(-errno);
 	}
 
 	/* now get our own pid */
-	our_pid = getpid();
+	our_pid = dev_getpid();
 	_debug( 2, "dev_relock() our own pid = %d\n", (int)our_pid);
 
 	/* first check for the FSSTND-1.2 lock, get the pid of the
@@ -825,18 +860,20 @@ dev_unlock (const char *devname,
 #endif /* DEBUG */
 	_debug( 3, "dev_unlock(%s, %d)\n", devname, (int)pid);
 	if (oldmask == -1 )
-		oldmask = umask( 0);	/* give full permissions to files created */
+		oldmask = umask( 002);	/* apply o-w to files created */
 	if ( ! (p=_dl_check_devname( devname)) )
 	 	close_n_return( -1);
-	strcpy( device, DEV_PATH);
-	strcat( device, p);	/* now device has a copy of the pathname */
+	snprintf(device, sizeof(device), "%s%s", DEV_PATH, p);
 	_debug( 2, "dev_unlock() device = %s\n", device);
 
 	/* check the device name for existence and retrieve the major
 	 * and minor numbers
 	 */
 	if ( stat( device, &statbuf) == -1 ) {
-		close_n_return( -1);
+		close_n_return(-errno);
+	}
+	if ( access( device, W_OK ) == -1 ) {
+		close_n_return(-errno);
 	}
 
 	/* first remove the FSSTND-1.2 lock, get the pid of the
diff --git a/src/lockdev.h b/src/lockdev.h
index 8830b73..a338735 100644
--- a/src/lockdev.h
+++ b/src/lockdev.h
@@ -43,12 +43,16 @@ extern "C" {
 #endif
 
 #include <sys/types.h>
+#include <errno.h>
 
 /* API of the library */
 
 void liblockdev_incr_debug (void);
 void liblockdev_reset_debug (void);
 
+pid_t dev_getpid ( void );
+pid_t dev_setpid ( pid_t pid );
+
 pid_t dev_testlock (const char *devname);
 
 pid_t dev_lock (const char *devname);
diff --git a/src/sample.c b/src/sample.c
index f0708b6..779723d 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -1,11 +1,13 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
 #include "lockdev.h"
 
 void
 usage (void)
 {
-	fprintf( stderr, "Usage: sample [-lurd] <device>\n" );
+	fprintf(stderr, "Usage: %s [-lud] <device>\n", "lockdev");
 	exit( -1 );
 }
 
@@ -14,8 +16,8 @@ int
 main (int   argc,
       char *argv[])
 {
-	int i, chld;
-	char *p, *dev, ch;
+	int i;
+	char *p = NULL, *dev = NULL, ch;
 
 	ch = '\0';
 	for( i = argc - 1; i > 0; i-- ) {
@@ -23,8 +25,7 @@ main (int   argc,
 		if( *p == '-' ) {
 			switch( *++p ) {
 			case 'l': 
-			case 'u': 
-			case 'r': ch = *p; break;
+			case 'u': ch = *p; break;
 			case 'd':
 				liblockdev_incr_debug();
 				break;
@@ -33,8 +34,10 @@ main (int   argc,
 		}
 		else dev = p;
 	}
-	fprintf( stderr, "option %c, device %s\n", ch, dev );
+	if (dev == NULL)
+	    usage();
 	i = 0;
+	(void) dev_setpid(getppid());
 	switch( ch ) {
 	case 'l':
 		i = dev_lock( dev);
@@ -42,22 +45,43 @@ main (int   argc,
 	case 'u':
 		i = dev_unlock( dev, 0);
 		break;
-	case 'r':
-		dev_lock( dev);
-		if(( chld = fork()) == 0 ) {
-			sleep(5);
-		}
-		else {
-			sleep( 1);
-			if (( i = dev_relock( dev, chld)) < 0 ) {
-				fprintf( stderr, "Relock failed in parent.\n" );
-			}
-		}
-		break;
 	default:
-		i = dev_testlock( dev);
+		if (dev)
+			i = dev_testlock( dev);
 		break;
 	}
+
+	/*
+	 * Exit		dev_lock	dev_unlock	dev_testlock
+	 *	  0	OK		OK		not locked
+	 *	  1	locked other	locked other	locked
+	 *	  2	EACCES
+	 *	  3	EROFS
+	 *	  4	EFAULT
+	 *	  5	EINVAL
+	 *	  6	ENAMETOOLONG
+	 *	  7	ENOENT
+	 *	  8	ENOTDIR
+	 *	  9	ENOMEM
+	 *	 10	ELOOP
+	 *	 11	EIO
+	 *	255	error		error		error
+	 */
+	switch (i) {
+	case -EACCES:	i = 2;	break;
+	case -EROFS:	i = 3;	break;
+	case -EFAULT:	i = 4;	break;
+	case -EINVAL:	i = 5;	break;
+	case -ENAMETOOLONG:	i = 6;	break;
+	case -ENOENT:	i = 7;	break;
+	case -ENOTDIR:	i = 8;	break;
+	case -ENOMEM:	i = 9;	break;
+	case -ELOOP:	i = 10;	break;
+	case -EIO:	i = 11;	break;
+	default:
+	    if (i < 0) i = 255;
+	    else if (i > 0) 	i = 1;
+	    break;
+	}
 	exit( i);
 }
-
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin