diff --git a/daemon/daemon.c b/daemon/daemon.c index d5b01eaed..27365e6d2 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -50,28 +50,30 @@ #include "torrents.h" static void usage ( const char *, ... ); -static void readargs ( int, char **, int *, int *, 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] = ""; +static char gl_pidfile[MAXPATHLEN] = ""; int main( int argc, char ** argv ) { struct event_base * evbase; int nofork, debug, sockfd; - char * sockpath; + char * sockpath, * pidfile; setmyname( argv[0] ); - readargs( argc, argv, &nofork, &debug, &sockpath ); + readargs( argc, argv, &nofork, &debug, &sockpath, &pidfile ); if( !nofork ) { @@ -83,6 +85,8 @@ main( int argc, char ** argv ) errsyslog( 1 ); } + if( 0 > savepid( pidfile ) ) + exit( 1 ); atexit( exitcleanup ); sockfd = trylocksock( sockpath ); if( 0 > sockfd ) @@ -118,7 +122,7 @@ usage( const char * msg, ... ) } printf( - "usage: %s [-dfh]\n" + "usage: %s [-dfh] [-p file] [-s file]\n" "\n" "Transmission %s http://transmission.m0k.org/\n" "A free, lightweight BitTorrent client with a simple, intuitive interface\n" @@ -126,6 +130,7 @@ usage( const char * msg, ... ) " -d --debug Print data send and received, implies -f\n" " -f --foreground Run in the foreground and log to stderr\n" " -h --help Display this message and exit\n" + " -p --pidfile Save the process id in a file at \n" " -s --socket Place the socket file at \n" "\n" "To add torrents or set options, use the transmission-remote program.\n", @@ -134,22 +139,25 @@ usage( const char * msg, ... ) } void -readargs( int argc, char ** argv, int * nofork, int * debug, char ** sock ) +readargs( int argc, char ** argv, int * nofork, int * debug, char ** sock, + char ** pidfile ) { - char optstr[] = "dfhs:"; + char optstr[] = "dfhp:s:"; struct option longopts[] = { { "debug", no_argument, NULL, 'd' }, { "foreground", no_argument, NULL, 'f' }, { "help", no_argument, NULL, 'h' }, + { "pidfile", required_argument, NULL, 'p' }, { "socket", required_argument, NULL, 's' }, { NULL, 0, NULL, 0 } }; int opt; - *nofork = 0; - *debug = 0; - *sock = NULL; + *nofork = 0; + *debug = 0; + *sock = NULL; + *pidfile = NULL; while( 0 <= ( opt = getopt_long( argc, argv, optstr, longopts, NULL ) ) ) { @@ -161,6 +169,9 @@ readargs( int argc, char ** argv, int * nofork, int * debug, char ** sock ) case 'f': *nofork = 1; break; + case 'p': + *pidfile = optarg; + break; case 's': *sock = optarg; break; @@ -294,6 +305,10 @@ exitcleanup( void ) unlink( gl_lockpath ); close( gl_lockfd ); } + if( 0 != gl_pidfile[0] ) + { + unlink( gl_pidfile ); + } } void @@ -338,3 +353,29 @@ gotsig( int sig, short what UNUSED, void * arg UNUSED ) raise( sig ); } } + +int +savepid( const char * file ) +{ + FILE * pid; + + pid = fopen( file, "wb" ); + if( NULL == pid ) + { + errnomsg( "failed to open pid file: %s", file ); + return -1; + } + + if( 0 > fprintf( pid, "%d\n", (int) getpid() ) ) + { + errnomsg( "failed to write pid to file: %s", file ); + fclose( pid ); + unlink( file ); + return -1; + } + + fclose( pid ); + strlcpy( gl_pidfile, file, sizeof gl_pidfile ); + + return 0; +} diff --git a/daemon/transmission-daemon.1 b/daemon/transmission-daemon.1 index 7d32f6e6b..a3711e3e2 100644 --- a/daemon/transmission-daemon.1 +++ b/daemon/transmission-daemon.1 @@ -32,6 +32,7 @@ .Fl h .Nm .Op Fl df +.Op Fl p Ar pid-file .Op Fl s Ar socket-file .Ek .Sh DESCRIPTION @@ -49,6 +50,13 @@ Run in the foreground and print errors to stderr instead of forking and logging errors with syslog. .It Fl h Fl -help Print command-line option descriptions. +.It Fl p Fl -pidfile Ar pid-file +Save the daemon's process ID in +.Ar pid-file . +.It Fl s Fl -socket Ar socket-file +Create the unix-domain socket file at +.Ar socket-file +instead of the platform-dependent default location. .El .Sh FILES .Pa ~/.transmission