1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-04-13 22:21:09 +02:00

See ChangeLog: Fri Nov 27 21:37:41 CET 1998 Werner Koch

This commit is contained in:
Werner Koch 1998-11-27 20:40:56 +00:00
parent d87a3c14c4
commit df1326eb05
11 changed files with 238 additions and 59 deletions

6
NEWS
View File

@ -1,7 +1,7 @@
* * The keyrings and the trustdb is now locked, so that
other GnuPG processes won't damage these files. You
may want to put the option --lock-once into your options file.
Noteworthy changes in version 0.4.4 Noteworthy changes in version 0.4.4

View File

@ -75,7 +75,7 @@ B<-k> [I<username>] [I<keyring>]
B<-kvc> List fingerprints B<-kvc> List fingerprints
B<-kvvc> List fingerprints and signatures B<-kvvc> List fingerprints and signatures
B<--list-keys> [I<names>] B<--list-keys> [I<names>]
List all keys from the public keyrings, or just the List all keys from the public keyrings, or just the
ones given on the command line. ones given on the command line.
@ -83,7 +83,7 @@ B<--list-secret-keys> [I<names>]
List all keys from the secret keyrings, or just the List all keys from the secret keyrings, or just the
ones given on the command line. ones given on the command line.
B<--list-sigs> [I<names>] B<--list-sigs> [I<names>]
Same as B<--list-keys>, but the signatures are listed Same as B<--list-keys>, but the signatures are listed
too. too.
@ -129,7 +129,7 @@ B<--edit-key> I<name>
B<delkey> B<delkey>
Remove a subkey. Remove a subkey.
B<expire> B<expire>
Change the key expiration time. If a key is Change the key expiration time. If a key is
select, the time of this key will be changed. select, the time of this key will be changed.
With no selection the key expiration of the With no selection the key expiration of the
primary key is changed. primary key is changed.
@ -190,7 +190,7 @@ B<--export-secret-keys> [I<names>
This is normally not very useful. This is normally not very useful.
B<--import>, B<--fast-import> B<--import>, B<--fast-import>
Import/merge keys. The fast version does not build Import/merge keys. The fast version does not build
the trustdb; this can be deon at anytime with the the trustdb; this can be deon at anytime with the
command B<--update-trustdb>. command B<--update-trustdb>.
@ -207,7 +207,7 @@ B<--import-ownertrust> [I<filename>]
Long options can be put in an options file (default F<~/.gnupg/options>); Long options can be put in an options file (default F<~/.gnupg/options>);
do not write the 2 dashes, but simply the name of the option and any do not write the 2 dashes, but simply the name of the option and any
arguments if required. Lines with a hash as the first non-white-space arguments if required. Lines with a hash as the first non-white-space
character are ignored. Commands may be put in this file too, but that character are ignored. Commands may be put in this file too, but that
does not make sense. does not make sense.
@ -426,6 +426,11 @@ B<--force-v3-sigs>
signatures on key material. This options forces signatures on key material. This options forces
v3 signatures for signatures on data. v3 signatures for signatures on data.
B<--lock-once>
Lock the file the first time a lock is requested
and do not release the lock until the process
terminates.
B<--no-verbose> B<--no-verbose>
Reset verbose level to 0. Reset verbose level to 0.
@ -466,11 +471,11 @@ a signature was bad and other errorcode for fatal errors.
=head1 EXAMPLES =head1 EXAMPLES
-se -r Bob [file] sign and encrypt for user Bob -se -r Bob [file] sign and encrypt for user Bob
-sat [file] make a clear text signature -sat [file] make a clear text signature
-sb [file] make a detached signature -sb [file] make a detached signature
-k [userid] show keys -k [userid] show keys
-kc [userid] show fingerprint -kc [userid] show fingerprint
=head1 ENVIRONMENT =head1 ENVIRONMENT
@ -479,19 +484,22 @@ C<GNUPGHOME> If set, direcory used instead of F<~/.gnupg>.
=head1 FILES =head1 FILES
F<~/.gnupg/secring.gpg> The secret keyring F<~/.gnupg/secring.gpg> The secret keyring
F<~/.gnupg/secring.gpg.lock> and the lock file
F<~/.gnupg/pubring.gpg> The public keyring F<~/.gnupg/pubring.gpg> The public keyring
F<~/.gnupg/pubring.gpg.lock> and the lock file
F<~/.gnupg/trustdb.gpg> The trust database F<~/.gnupg/trustdb.gpg> The trust database
F<~/.gnupg/trustdb.gpg.lock> and the lock file
F<~/.gnupg/options> May contain options F<~/.gnupg/options> May contain options
F</usr[/local]/lib/gnupg/> Default location for extensions F</usr[/local]/lib/gnupg/> Default location for extensions
=head1 SEE ALSO =head1 SEE ALSO
gpg(1) gpgm(1) gpg(1) gpgm(1)
=head1 WARNINGS =head1 WARNINGS

View File

@ -1,3 +1,15 @@
Fri Nov 27 21:37:41 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* g10.c: New option --lock-once
* tdbio.c (open_db): Add an atexit
(cleanup): New.
(tdbio_sync): Add locking.
(tdbio_end_transaction): Ditto.
(put_record_into_cache): Ditto.
* ringedit.c (keyring_copy): Ditto.
(cleanup): New.
(add_keyblock_resource): Add an atexit.
Fri Nov 27 15:30:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de> Fri Nov 27 15:30:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* armor.c (find_header): Another fix for clearsigs. * armor.c (find_header): Another fix for clearsigs.

View File

@ -147,6 +147,7 @@ enum cmd_and_opt_values { aNull = 0,
oS2KCipher, oS2KCipher,
oCharset, oCharset,
oNotDashEscaped, oNotDashEscaped,
oLockOnce,
aTest }; aTest };
@ -295,6 +296,7 @@ static ARGPARSE_OPTS opts[] = {
{ oSetFilename, "set-filename", 2, "@" }, { oSetFilename, "set-filename", 2, "@" },
{ oComment, "comment", 2, "@" }, { oComment, "comment", 2, "@" },
{ oNotDashEscaped, "not-dash-escaped", 0, "@" }, { oNotDashEscaped, "not-dash-escaped", 0, "@" },
{ oLockOnce, "lock-once", 0, "@" },
{0} }; {0} };
@ -768,6 +770,7 @@ main( int argc, char **argv )
pargs.r.ret_str); pargs.r.ret_str);
break; break;
case oNotDashEscaped: opt.not_dash_escaped = 1; break; case oNotDashEscaped: opt.not_dash_escaped = 1; break;
case oLockOnce: opt.lock_once = 1; break;
default : pargs.err = configfp? 1:2; break; default : pargs.err = configfp? 1:2; break;
} }

View File

@ -65,6 +65,7 @@ struct {
int s2k_digest_algo; int s2k_digest_algo;
int s2k_cipher_algo; int s2k_cipher_algo;
int not_dash_escaped; int not_dash_escaped;
int lock_once;
} opt; } opt;

View File

@ -46,3 +46,9 @@ compress-algo 1
# everytime you use --mynames, it will be expanded to the options # everytime you use --mynames, it will be expanded to the options
# in the above defintion. The name of the alias may not be abbreviated. # in the above defintion. The name of the alias may not be abbreviated.
# lock tthe file only once for the lifetime of a process.
# if you do not define this, the lock will be obtained and released
# every time it is needed - normally this is not needed.
lock-once

View File

@ -77,6 +77,7 @@ typedef struct resource_table_struct RESTBL;
#define MAX_RESOURCES 10 #define MAX_RESOURCES 10
static RESTBL resource_table[MAX_RESOURCES]; static RESTBL resource_table[MAX_RESOURCES];
static const char *keyring_lock;
static int search( PACKET *pkt, KBPOS *kbpos, int secret ); static int search( PACKET *pkt, KBPOS *kbpos, int secret );
@ -116,6 +117,15 @@ fatal_gdbm_error( const char *string )
#endif /* HAVE_LIBGDBM */ #endif /* HAVE_LIBGDBM */
static void
cleanup( void )
{
if( keyring_lock ) {
release_dotlock( keyring_lock );
keyring_lock = NULL;
}
}
/**************************************************************** /****************************************************************
****************** public functions **************************** ****************** public functions ****************************
****************************************************************/ ****************************************************************/
@ -152,6 +162,7 @@ enum_keyblock_resources( int *sequence, int secret )
int int
add_keyblock_resource( const char *url, int force, int secret ) add_keyblock_resource( const char *url, int force, int secret )
{ {
static int initialized = 0;
static int any_secret, any_public; static int any_secret, any_public;
const char *resname = url; const char *resname = url;
IOBUF iobuf = NULL; IOBUF iobuf = NULL;
@ -160,6 +171,11 @@ add_keyblock_resource( const char *url, int force, int secret )
int rc = 0; int rc = 0;
enum resource_type rt = rt_UNKNOWN; enum resource_type rt = rt_UNKNOWN;
if( !initialized ) {
initialized = 1;
atexit( cleanup );
}
/* Do we have an URL? /* Do we have an URL?
* gnupg-gdbm:filename := this is a GDBM resource * gnupg-gdbm:filename := this is a GDBM resource
* gnupg-ring:filename := this is a plain keyring * gnupg-ring:filename := this is a plain keyring
@ -843,7 +859,7 @@ update_keyblock( KBPOS *kbpos, KBNODE root )
* *
* A string "GnuPG user db", a \n. * A string "GnuPG user db", a \n.
* user ids of one key, delimited by \t, * user ids of one key, delimited by \t,
* a # or ^ followed by a 20 byte fingerprint, followed by an \n * a # or ^ followed by a 20 byte fingerprint, followed by an \n
* The literal characters =, \n, \t, #, ^ must be replaced by a equal sign * The literal characters =, \n, \t, #, ^ must be replaced by a equal sign
* and their hex value. * and their hex value.
* *
@ -1224,6 +1240,11 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
if( kbpos->fp ) if( kbpos->fp )
BUG(); /* not allowed with such a handle */ BUG(); /* not allowed with such a handle */
if( !keyring_lock );
keyring_lock = make_dotlock( rentry->fname, -1 );
if( !keyring_lock )
log_fatal("can't lock '%s'\n", rentry->fname );
/* open the source file */ /* open the source file */
fp = iobuf_fopen( rentry->fname, "rb" ); fp = iobuf_fopen( rentry->fname, "rb" );
if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */ if( mode == 1 && !fp && errno == ENOENT ) { /* no file yet */
@ -1233,6 +1254,10 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
newfp = iobuf_create( rentry->fname ); newfp = iobuf_create( rentry->fname );
if( !newfp ) { if( !newfp ) {
log_error(_("%s: can't create: %s\n"), rentry->fname, strerror(errno)); log_error(_("%s: can't create: %s\n"), rentry->fname, strerror(errno));
if( !opt.lock_once ) {
release_dotlock( keyring_lock );
keyring_lock = NULL;
}
return G10ERR_OPEN_FILE; return G10ERR_OPEN_FILE;
} }
else else
@ -1244,16 +1269,28 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
log_error("build_packet(%d) failed: %s\n", log_error("build_packet(%d) failed: %s\n",
node->pkt->pkttype, g10_errstr(rc) ); node->pkt->pkttype, g10_errstr(rc) );
iobuf_cancel(newfp); iobuf_cancel(newfp);
if( !opt.lock_once ) {
release_dotlock( keyring_lock );
keyring_lock = NULL;
}
return G10ERR_WRITE_FILE; return G10ERR_WRITE_FILE;
} }
} }
if( iobuf_close(newfp) ) { if( iobuf_close(newfp) ) {
log_error("%s: close failed: %s\n", rentry->fname, strerror(errno)); log_error("%s: close failed: %s\n", rentry->fname, strerror(errno));
if( !opt.lock_once ) {
release_dotlock( keyring_lock );
keyring_lock = NULL;
}
return G10ERR_CLOSE_FILE; return G10ERR_CLOSE_FILE;
} }
if( chmod( rentry->fname, S_IRUSR | S_IWUSR ) ) { if( chmod( rentry->fname, S_IRUSR | S_IWUSR ) ) {
log_error("%s: chmod failed: %s\n", log_error("%s: chmod failed: %s\n",
rentry->fname, strerror(errno) ); rentry->fname, strerror(errno) );
if( !opt.lock_once ) {
release_dotlock( keyring_lock );
keyring_lock = NULL;
}
return G10ERR_WRITE_FILE; return G10ERR_WRITE_FILE;
} }
return 0; return 0;
@ -1418,6 +1455,10 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
} }
leave: leave:
if( !opt.lock_once ) {
release_dotlock( keyring_lock );
keyring_lock = NULL;
}
m_free(bakfname); m_free(bakfname);
m_free(tmpfname); m_free(tmpfname);
return rc; return rc;

View File

@ -77,6 +77,7 @@ struct cmp_sdir_struct {
static char *db_name; static char *db_name;
static const char *lockname;
static int db_fd = -1; static int db_fd = -1;
static int in_transaction; static int in_transaction;
@ -235,6 +236,10 @@ put_record_into_cache( ulong recno, const char *data )
int n = dirty_count / 5; /* discard some dirty entries */ int n = dirty_count / 5; /* discard some dirty entries */
if( !n ) if( !n )
n = 1; n = 1;
if( !lockname )
lockname = make_dotlock( db_name, -1 );
if( !lockname )
log_fatal("can't get a lock - giving up\n");
for( unused = NULL, r = cache_list; r; r = r->next ) { for( unused = NULL, r = cache_list; r; r = r->next ) {
if( r->flags.used && r->flags.dirty ) { if( r->flags.used && r->flags.dirty ) {
int rc = write_cache_item( r ); int rc = write_cache_item( r );
@ -248,6 +253,10 @@ put_record_into_cache( ulong recno, const char *data )
break; break;
} }
} }
if( !opt.lock_once ) {
release_dotlock( lockname );
lockname=NULL;
}
assert( unused ); assert( unused );
r = unused; r = unused;
r->flags.used = 1; r->flags.used = 1;
@ -276,6 +285,7 @@ int
tdbio_sync() tdbio_sync()
{ {
CACHE_CTRL r; CACHE_CTRL r;
int did_lock = 0;
if( in_transaction ) if( in_transaction )
log_bug("tdbio: syncing while in transaction\n"); log_bug("tdbio: syncing while in transaction\n");
@ -283,6 +293,12 @@ tdbio_sync()
if( !cache_is_dirty ) if( !cache_is_dirty )
return 0; return 0;
if( !lockname ) {
lockname = make_dotlock( db_name, -1 );
did_lock = 1;
if( !lockname )
log_fatal("can't get a lock - giving up\n");
}
for( r = cache_list; r; r = r->next ) { for( r = cache_list; r; r = r->next ) {
if( r->flags.used && r->flags.dirty ) { if( r->flags.used && r->flags.dirty ) {
int rc = write_cache_item( r ); int rc = write_cache_item( r );
@ -291,6 +307,10 @@ tdbio_sync()
} }
} }
cache_is_dirty = 0; cache_is_dirty = 0;
if( did_lock && !opt.lock_once ) {
release_dotlock( lockname );
lockname=NULL;
}
return 0; return 0;
} }
@ -324,10 +344,18 @@ tdbio_end_transaction()
if( !in_transaction ) if( !in_transaction )
log_bug("tdbio: no active transaction\n"); log_bug("tdbio: no active transaction\n");
if( !lockname )
lockname = make_dotlock( db_name, -1 );
if( !lockname )
log_fatal("can't get a lock - giving up\n");
block_all_signals(); block_all_signals();
in_transaction = 0; in_transaction = 0;
rc = tdbio_sync(); rc = tdbio_sync();
unblock_all_signals(); unblock_all_signals();
if( !opt.lock_once ) {
release_dotlock( lockname );
lockname=NULL;
}
return rc; return rc;
} }
@ -452,6 +480,14 @@ tdbio_get_dbname()
} }
static void
cleanup(void)
{
if( lockname ) {
release_dotlock(lockname);
lockname = NULL;
}
}
static void static void
open_db() open_db()
@ -468,7 +504,7 @@ open_db()
log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) ); log_fatal( _("%s: can't open: %s\n"), db_name, strerror(errno) );
if( tdbio_read_record( 0, &rec, RECTYPE_VER ) ) if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
log_fatal( _("%s: invalid trust-db\n"), db_name ); log_fatal( _("%s: invalid trust-db\n"), db_name );
/* fixme: check ->locked and other stuff */ atexit( cleanup );
} }

View File

@ -126,6 +126,13 @@ const char *default_strusage( int level );
const char *strusage( int level ); const char *strusage( int level );
/*-- dotlock.c --*/
const char *make_dotlock( const char *file_to_lock, long timeout );
int release_dotlock( const char *lockfile );
/*-- fileutil.c --*/ /*-- fileutil.c --*/
char * make_basename(const char *filepath); char * make_basename(const char *filepath);
char * make_dirname(const char *filepath); char * make_dirname(const char *filepath);

View File

@ -1,3 +1,7 @@
Fri Nov 27 21:37:41 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* dotlock.c: Implemented
Wed Nov 25 11:30:07 1998 Werner Koch (wk@isil.d.shuttle.de) Wed Nov 25 11:30:07 1998 Werner Koch (wk@isil.d.shuttle.de)
* iobuf.c (iobuf_pop_filter): Fixed sigsegv after error. * iobuf.c (iobuf_pop_filter): Fixed sigsegv after error.

View File

@ -23,14 +23,20 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "types.h" #include "types.h"
#include "util.h" #include "util.h"
#include "memory.h" #include "memory.h"
static int read_lockfile( const char *name );
#if 0
/**************** /****************
* Create a lockfile with the given name. A TIMEOUT of 0 * Create a lockfile with the given name. A TIMEOUT of 0
* returns immediately, -1 waits forever (hopefully not), other * returns immediately, -1 waits forever (hopefully not), other
@ -40,67 +46,122 @@
* *
* Notes: This function creates a lock file in the same directory * Notes: This function creates a lock file in the same directory
* as file_to_lock with the name "file_to_lock.lock" * as file_to_lock with the name "file_to_lock.lock"
* A temporary file ".#lk.<pid>.<hostname> is used. * A temporary file ".#lk.<hostname>.pid[.threadid] is used.
* This function does nothing for Windoze. * This function does nothing for Windoze.
*/ */
const char * const char *
make_dotlock( const char *file_to_lock, long timeout ) make_dotlock( const char *file_to_lock, long timeout )
{ {
int rc=-1, fd=-1, pid; int fd=-1, pid;
char pidstr[16]; char pidstr[16];
const char *handle = NULL;
char *lockname = NULL;
char *tname = NULL; char *tname = NULL;
char *p; int have_tfile = 0;
struct utsname uts;
const char *dirpart;
int dirpartlen;
log_debug("dotlock_make: lock='%s'\n", lockfile );
sprintf( pidstr, "%10d\n", getpid() ); sprintf( pidstr, "%10d\n", getpid() );
/* add the hostname to the second line (FQDN or IP addr?) */ /* fixme: add the hostname to the second line (FQDN or IP addr?) */
/* create a temporary file */ /* create a temporary file */
tname = CreateTmpFile2( p, ".#lk" ); #if SYS_NMLN < 8
free(p); #error Aiiih
if( !tname ) #endif
log_fatal( "could not create temporary lock file '%s'\n"); if( uname( &uts ) )
log_debug( "dotlock_make: tmpname='%s'\n", tname ); strcpy( uts.nodename, "unknown" );
chmod( tname, 0644 ); /* just in case an umask is set */
if( !(fd = open( tname, O_WRONLY )) ) if( !(dirpart = strrchr( file_to_lock, '/' )) ) {
log_fatal( "could not open temporary lock file '%s'\n", tname); dirpart = ".";
if( write(fd, pidstr, 11 ) != 11 ) dirpartlen = 1;
log_fatal( "error writing to temporary lock file '%s'\n", tname); }
else {
dirpartlen = dirpart - file_to_lock;
dirpart = file_to_lock;
}
#ifdef _THREAD_SAFE
tname = m_alloc( dirpartlen + 6 + strlen(uts.nodename) + 11+ 20 );
sprintf( tname, "%.*s/.#lk.%s.%d.%p",
dirpartlen, dirpart, uts.nodename, getpid(), &pid );
#else
tname = m_alloc( dirpartlen + 6 + strlen(uts.nodename) + 11 );
sprintf( tname, "%.*s/.#lk.%s.%d",
dirpartlen, dirpart, uts.nodename, getpid() );
#endif
do {
errno = 0;
fd = open( tname, O_WRONLY|O_CREAT|O_EXCL,
S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR );
} while( fd == -1 && errno == EINTR );
if( fd == -1 ) {
log_error( "failed to create temporary file '%s': %s\n",
tname, strerror(errno));
goto leave;
}
have_tfile = 1;
if( write(fd, pidstr, 11 ) != 11 ) {
log_fatal( "error writing to '%s': %s\n", tname, strerror(errno) );
goto leave;
}
if( close(fd) ) { if( close(fd) ) {
log_fatal( "error closing '%s'\n", tname); log_error( "error closing '%s': %s\n", tname, strerror(errno));
goto leave;
}
fd = -1;
lockname = m_alloc( strlen(file_to_lock) + 6 );
strcpy(stpcpy(lockname, file_to_lock), ".lock");
retry: retry:
if( !link(tname, lockfile) ) if( !link(tname, lockname) ) {/* fixme: better use stat to check the link count */
rc = 0; /* okay */ handle = lockname;
else if( errno != EEXIST ) lockname = NULL;
log_error( "lock not made: link() failed: %s\n", strerror(errno) ); }
else { /* lock file already there */ else if( errno == EEXIST ) {
if( (pid = read_lockfile(lockfile)) == -1 ) { if( (pid = read_lockfile(lockname)) == -1 ) {
if( errno == ENOENT ) { if( errno == ENOENT ) {
log_debug( "lockfile disappeared\n"); log_info( "lockfile disappeared\n");
goto retry; goto retry;
} }
log_debug("cannot read lockfile\n"); log_info("cannot read lockfile\n");
} }
else if( pid == getpid() ) { else if( pid == getpid() ) {
log_info( "Oops: lock already hold by us\n"); log_info( "Oops: lock already hold by us\n");
rc = 0; /* okay */ handle = lockname;
lockname = NULL;
} }
#if 0 /* we should not do this without checking the permissions */
/* and the hostname */
else if( kill(pid, 0) && errno == ESRCH ) { else if( kill(pid, 0) && errno == ESRCH ) {
log_info( "removing stale lockfile (created by %d)", (int)pid ); log_info( "removing stale lockfile (created by %d)", pid );
remove( lockfile ); remove( lockname );
goto retry; goto retry;
} }
log_debug( "lock not made: lock file exists\n" ); #endif
if( timeout == -1 ) {
struct timeval tv;
log_info( "waiting for lock (hold by %d) ...\n", pid );
/* can't use sleep, cause signals may be blocked */
tv.tv_sec = 1;
tv.tv_usec = 0;
select(0, NULL, NULL, NULL, &tv);
goto retry;
}
/* fixme: implement timeouts */
} }
else
log_error( "lock not made: link() failed: %s\n", strerror(errno) );
if( tname ) { leave:
if( fd != -1 )
close(fd);
if( have_tfile )
remove(tname); remove(tname);
free(tname); m_free(tname);
} m_free(lockname);
if( !rc ) return handle;
log_debug( "lock made\n");
return rc;
} }
/**************** /****************
@ -140,7 +201,7 @@ release_dotlock( const char *lockfile )
lockfile); lockfile);
return -1; return -1;
} }
log_debug( "release_dotlock: released lockfile '%s'", lockfile); m_free( (char*)lockfile );
return 0; return 0;
} }
@ -156,7 +217,7 @@ read_lockfile( const char *name )
if( (fd = open(name, O_RDONLY)) == -1 ) { if( (fd = open(name, O_RDONLY)) == -1 ) {
int e = errno; int e = errno;
log_debug("error opening lockfile '%s'", name ); log_debug("error opening lockfile '%s': %s\n", name, strerror(errno) );
errno = e; errno = e;
return -1; return -1;
} }
@ -175,4 +236,4 @@ read_lockfile( const char *name )
} }
return pid; return pid;
} }
#endif