src/lib/daemon.c in trema-0.3.14 vs src/lib/daemon.c in trema-0.3.15
- old
+ new
@@ -24,10 +24,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <getopt.h>
#include "checks.h"
#include "log.h"
#include "wrapper.h"
@@ -288,15 +289,88 @@
return -1;
}
exe_path[ readsiz ] = '\0';
char *exe_name = basename( exe_path );
- if ( strcmp( name, exe_name ) != 0 ) {
- warn( "Failed to check process name %s ( %s [%d] ).", name, strerror( errno ), errno );
+ if ( strcmp( name, exe_name ) == 0 ) {
+ return pid;
+ }
+
+ // check if -n (service_name) option is used
+ sprintf( proc_path, "/proc/%d/cmdline", pid );
+ fd = open( proc_path, O_RDONLY, 0 );
+ if ( fd < 0 ) {
+ warn( "Failed to open %s ( %s [%d] ).", proc_path, strerror( errno ), errno );
return -1;
}
- return pid;
+ char *buffer = xcalloc( PATH_MAX + 2, sizeof( char ) );
+ char *write_head = buffer;
+ size_t buffer_left = PATH_MAX;
+ size_t read_byte = 0;
+ while ( ( readsiz = read( fd, write_head, buffer_left ) ) > 0 ) {
+ read_byte += ( size_t ) readsiz;
+ write_head += readsiz;
+ buffer_left = PATH_MAX - read_byte;
+ }
+ close( fd );
+
+ // convert cmdline to argv format
+ size_t argc = 0;
+ char **argv = xcalloc( 1, sizeof( char * ) );
+
+ char *token = buffer;
+ const char *buffer_end = buffer + read_byte;
+ while ( token <= buffer_end ) {
+ size_t token_len = strlen( token );
+ if ( token_len > 0 ) {
+ ++argc;
+ char **new_argv = xmalloc( ( argc + 1 ) * sizeof( char * ) );
+ for ( size_t i = 0; i < argc - 1; ++i ) {
+ new_argv[ i ] = argv[ i ];
+ }
+ xfree( argv );
+ argv = new_argv;
+ argv[ argc - 1 ] = token;
+ argv[ argc ] = NULL;
+ }
+ else {
+ if ( *( token + 1 ) == '\0' ) {
+ // "\0\0", end of cmdline
+ break;
+ }
+ }
+ token += token_len + 1;
+ }
+
+ const struct option long_options[] = {
+ { "name", 1, NULL, 'n' },
+ { NULL, 0, NULL, 0 },
+ };
+ const char short_options[] = "n:";
+ int c;
+ optind = 0;
+ opterr = 0;
+ const char *service_name = basename( argv[ 0 ] );
+ while ( ( c = getopt_long( ( int )argc, argv, short_options, long_options, NULL ) ) != -1 ){
+ switch ( c ) {
+ case 'n':
+ service_name = optarg;
+ break;
+ }
+ }
+
+ if ( strcmp( name, service_name ) == 0 ) {
+ xfree( argv );
+ xfree( buffer );
+ return pid;
+ }
+ else {
+ warn( "Failed to check process name %s.", name );
+ xfree( argv );
+ xfree( buffer );
+ return -1;
+ }
}
void
rename_pid( const char *directory, const char *old, const char *new ) {