add win32/posix wrapper function tr_lockfile() to libT and use it in daemon/gtk.
This commit is contained in:
parent
288547ffb8
commit
d870c12f40
|
@ -32,7 +32,6 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <event.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -42,6 +41,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <libtransmission/trcompat.h>
|
||||
#include <libtransmission/platform.h>
|
||||
#include <libtransmission/version.h>
|
||||
|
||||
#include "errors.h"
|
||||
|
@ -52,14 +52,12 @@
|
|||
static void usage ( const char *, ... );
|
||||
static void readargs ( int, char **, int *, int *, char **, char ** );
|
||||
static int trylocksock ( const char * );
|
||||
static int getlock ( const char * );
|
||||
static int getsock ( const char * );
|
||||
static void exitcleanup ( void );
|
||||
static void setupsigs ( struct event_base * );
|
||||
static void gotsig ( int, short, void * );
|
||||
static int savepid ( const char * );
|
||||
|
||||
static int gl_lockfd = -1;
|
||||
static char gl_lockpath[MAXPATHLEN] = "";
|
||||
static int gl_sockfd = -1;
|
||||
static char gl_sockpath[MAXPATHLEN] = "";
|
||||
|
@ -183,6 +181,28 @@ readargs( int argc, char ** argv, int * nofork, int * debug, char ** sock,
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
getlock( const char * filename )
|
||||
{
|
||||
const int state = tr_lockfile( filename );
|
||||
const int success = state == TR_LOCKFILE_SUCCESS;
|
||||
|
||||
if( !success ) switch( state ) {
|
||||
case TR_LOCKFILE_EOPEN:
|
||||
errnomsg( "failed to open file: %s", filename );
|
||||
break;
|
||||
case TR_LOCKFILE_ELOCK:
|
||||
errmsg( "another copy of %s is already running", getmyname() );
|
||||
break;
|
||||
default:
|
||||
errmsg( "unhandled tr_lockfile error: %d", state );
|
||||
break;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
trylocksock( const char * sockpath )
|
||||
{
|
||||
|
@ -197,12 +217,8 @@ trylocksock( const char * sockpath )
|
|||
}
|
||||
|
||||
confpath( path, sizeof path, CONF_FILE_LOCK, 0 );
|
||||
fd = getlock( path );
|
||||
if( 0 > fd )
|
||||
{
|
||||
if( !getlock( path ) )
|
||||
return -1;
|
||||
}
|
||||
gl_lockfd = fd;
|
||||
strlcpy( gl_lockpath, path, sizeof gl_lockpath );
|
||||
|
||||
if( NULL == sockpath )
|
||||
|
@ -221,46 +237,6 @@ trylocksock( const char * sockpath )
|
|||
return fd;
|
||||
}
|
||||
|
||||
int
|
||||
getlock( const char * path )
|
||||
{
|
||||
struct flock lk;
|
||||
int fd;
|
||||
char pid[64];
|
||||
|
||||
fd = open( path, O_RDWR | O_CREAT, 0666 );
|
||||
if( 0 > fd )
|
||||
{
|
||||
errnomsg( "failed to open file: %s", path );
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset( &lk, 0, sizeof lk );
|
||||
lk.l_start = 0;
|
||||
lk.l_len = 0;
|
||||
lk.l_type = F_WRLCK;
|
||||
lk.l_whence = SEEK_SET;
|
||||
if( 0 > fcntl( fd, F_SETLK, &lk ) )
|
||||
{
|
||||
if( EAGAIN == errno )
|
||||
{
|
||||
errmsg( "another copy of %s is already running", getmyname() );
|
||||
}
|
||||
else
|
||||
{
|
||||
errnomsg( "failed to obtain lock on file: %s", path );
|
||||
}
|
||||
close( fd );
|
||||
return -1;
|
||||
}
|
||||
|
||||
ftruncate( fd, 0 );
|
||||
snprintf( pid, sizeof pid, "%i\n", getpid() );
|
||||
write( fd, pid, strlen( pid ) );
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
int
|
||||
getsock( const char * path )
|
||||
{
|
||||
|
@ -305,11 +281,9 @@ exitcleanup( void )
|
|||
{
|
||||
unlink( gl_pidfile );
|
||||
}
|
||||
if( 0 <= gl_lockfd )
|
||||
{
|
||||
|
||||
if( *gl_lockpath )
|
||||
unlink( gl_lockpath );
|
||||
close( gl_lockfd );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
64
gtk/conf.c
64
gtk/conf.c
|
@ -28,9 +28,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -39,6 +36,7 @@
|
|||
|
||||
#include <libtransmission/transmission.h>
|
||||
#include <libtransmission/bencode.h>
|
||||
#include <libtransmission/platform.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "util.h"
|
||||
|
@ -72,47 +70,27 @@ cf_init(const char *dir, char **errstr)
|
|||
***/
|
||||
|
||||
/* errstr may be NULL, this might be called before GTK is initialized */
|
||||
static int
|
||||
lockfile(const char *file, char **errstr)
|
||||
static gboolean
|
||||
lockfile(const char * filename, char **errstr)
|
||||
{
|
||||
int fd;
|
||||
struct flock lk;
|
||||
const int state = tr_lockfile( filename );
|
||||
const gboolean success = state == TR_LOCKFILE_SUCCESS;
|
||||
|
||||
if( errstr )
|
||||
*errstr = NULL;
|
||||
|
||||
fd = open( file, O_RDWR | O_CREAT, 0666 );
|
||||
if( fd < 0 )
|
||||
{
|
||||
const int savederr = errno;
|
||||
if( errstr )
|
||||
*errstr = g_strdup_printf(
|
||||
_("Failed to open the file %s for writing:\n%s"),
|
||||
file, g_strerror( errno ) );
|
||||
errno = savederr;
|
||||
return -1;
|
||||
if( errstr ) switch( state ) {
|
||||
case TR_LOCKFILE_EOPEN:
|
||||
*errstr = g_strdup_printf( _("Failed to open lockfile %s: %s"),
|
||||
filename, g_strerror( errno ) );
|
||||
break;
|
||||
case TR_LOCKFILE_ELOCK:
|
||||
*errstr = g_strdup_printf( _( "%s is already running." ),
|
||||
g_get_application_name( ) );
|
||||
break;
|
||||
case TR_LOCKFILE_SUCCESS:
|
||||
*errstr = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
memset( &lk, 0, sizeof( lk ) );
|
||||
lk.l_start = 0;
|
||||
lk.l_len = 0;
|
||||
lk.l_type = F_WRLCK;
|
||||
lk.l_whence = SEEK_SET;
|
||||
if( -1 == fcntl( fd, F_SETLK, &lk ) )
|
||||
{
|
||||
const int savederr = errno;
|
||||
if( errstr )
|
||||
*errstr = ( errno == EAGAIN )
|
||||
? g_strdup_printf( _( "Another copy of %s is already running." ),
|
||||
g_get_application_name( ) )
|
||||
: g_strdup_printf( _( "Failed to lock the file %s:\n%s" ),
|
||||
file, g_strerror( errno ) );
|
||||
close( fd );
|
||||
errno = savederr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
return success;
|
||||
}
|
||||
|
||||
static char*
|
||||
|
@ -134,12 +112,12 @@ gboolean
|
|||
cf_lock( char ** errstr )
|
||||
{
|
||||
char * path = getLockFilename( );
|
||||
int fd = lockfile( path, errstr );
|
||||
if( fd >= 0 )
|
||||
const gboolean didLock = lockfile( path, errstr );
|
||||
if( didLock )
|
||||
gl_lockpath = g_strdup( path );
|
||||
g_atexit( cf_removelocks );
|
||||
g_free( path );
|
||||
return fd >= 0;
|
||||
return didLock;
|
||||
}
|
||||
|
||||
char*
|
||||
|
|
|
@ -449,3 +449,51 @@ tr_getTorrentsDirectory( void )
|
|||
init = 1;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/***
|
||||
****
|
||||
***/
|
||||
|
||||
int
|
||||
tr_lockfile( const char * filename )
|
||||
{
|
||||
int ret;
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
HANDLE file = CreateFile( filename,
|
||||
GENERIC_READ|GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL );
|
||||
if( file == INVALID_HANDLE_VALUE )
|
||||
ret = TR_LOCKFILE_EOPEN;
|
||||
else if( !LockFile( file, 0, 0, 1, 1 ) )
|
||||
ret = TR_LOCKFILE_ELOCK;
|
||||
else
|
||||
ret = TR_LOCKFILE_SUCCESS;
|
||||
|
||||
#else
|
||||
|
||||
int fd = open( filename, O_RDWR | O_CREAT, 0666 );
|
||||
if( fd < 0 )
|
||||
ret = TR_LOCKFILE_EOPEN;
|
||||
else {
|
||||
struct flock lk;
|
||||
memset( &lk, 0, sizeof( lk ) );
|
||||
lk.l_start = 0;
|
||||
lk.l_len = 0;
|
||||
lk.l_type = F_WRLCK;
|
||||
lk.l_whence = SEEK_SET;
|
||||
if( -1 == fcntl( fd, F_SETLK, &lk ) )
|
||||
ret = TR_LOCKFILE_ELOCK;
|
||||
else
|
||||
ret = TR_LOCKFILE_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -48,4 +48,14 @@ void tr_lockLock ( tr_lock * );
|
|||
void tr_lockUnlock ( tr_lock * );
|
||||
int tr_lockHave ( const tr_lock * );
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
TR_LOCKFILE_SUCCESS,
|
||||
TR_LOCKFILE_EOPEN,
|
||||
TR_LOCKFILE_ELOCK
|
||||
};
|
||||
|
||||
int tr_lockfile ( const char * filename );
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue