1111#define environ (*_NSGetEnviron())
1212#endif
1313
14+ #ifdef OS_UNIX
15+ #include <sys/file.h>
16+ #endif
17+
18+ static FILE * s_fp = NULL ;
19+
1420main_ctx_t g_main_ctx ;
1521
1622static void init_arg_kv (int maxsize ) {
@@ -73,7 +79,7 @@ int main_ctx_init(int argc, char** argv) {
7379 get_executable_path (argv [0 ], MAX_PATH );
7480 }
7581
76- get_run_dir (g_main_ctx .run_dir , sizeof (g_main_ctx .run_dir ));
82+ if (! hv_exists ( g_main_ctx . run_dir )) get_run_dir (g_main_ctx .run_dir , sizeof (g_main_ctx .run_dir ));
7783 //printf("run_dir=%s\n", g_main_ctx.run_dir);
7884 strncpy (g_main_ctx .program_name , hv_basename (argv [0 ]), sizeof (g_main_ctx .program_name ));
7985#ifdef OS_WIN
@@ -89,21 +95,36 @@ int main_ctx_init(int argc, char** argv) {
8995 snprintf (g_main_ctx .pidfile , sizeof (g_main_ctx .pidfile ), "%s/logs/%s.pid" , g_main_ctx .run_dir , g_main_ctx .program_name );
9096 snprintf (g_main_ctx .logfile , sizeof (g_main_ctx .logfile ), "%s/logs/%s.log" , g_main_ctx .run_dir , g_main_ctx .program_name );
9197 hlog_set_file (g_main_ctx .logfile );
92-
98+ #ifdef OS_WIN
99+ // Only Windows does not allow deleting occupied files
100+ remove (g_main_ctx .pidfile );
101+ #endif
93102 g_main_ctx .pid = getpid ();
94103 g_main_ctx .oldpid = getpid_from_pidfile ();
95104#ifdef OS_UNIX
96- if (kill (g_main_ctx .oldpid , 0 ) == -1 && errno == ESRCH ) {
97- g_main_ctx .oldpid = -1 ;
105+ s_fp = fopen (g_main_ctx .pidfile , "a" );
106+ if (s_fp != NULL ) {
107+ if (flock (fileno (s_fp ), LOCK_EX | LOCK_NB ) == 0 ) {
108+ // The lock is successful, indicating that oldpid has ended
109+ g_main_ctx .oldpid = -1 ;
110+ flock (fileno (s_fp ), LOCK_UN );
111+ }
112+ fclose (s_fp );
113+ s_fp = NULL ;
98114 }
99- #else
100- HANDLE hproc = OpenProcess (PROCESS_TERMINATE , FALSE, g_main_ctx .oldpid );
101- if (hproc == NULL ) {
115+ if (kill (g_main_ctx .oldpid , 0 ) == -1 && errno == ESRCH ) {
102116 g_main_ctx .oldpid = -1 ;
103117 }
104- else {
118+ #endif
119+
120+ #ifdef OS_WIN
121+ DWORD exitCode = 0 ;
122+ const HANDLE hproc = OpenProcess (PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION , FALSE, g_main_ctx .oldpid );
123+ if (hproc ) {
124+ GetExitCodeProcess (hproc , & exitCode );
105125 CloseHandle (hproc );
106126 }
127+ if (exitCode != STILL_ACTIVE ) g_main_ctx .oldpid = -1 ;
107128#endif
108129
109130 // save arg
@@ -429,22 +450,38 @@ void setproctitle(const char* fmt, ...) {
429450#endif
430451
431452int create_pidfile () {
432- FILE * fp = fopen (g_main_ctx .pidfile , "w " );
433- if (fp == NULL ) {
453+ s_fp = fopen (g_main_ctx .pidfile , "a " );
454+ if (s_fp == NULL ) {
434455 hloge ("fopen('%s') error: %d" , g_main_ctx .pidfile , errno );
435456 return -1 ;
436457 }
437-
458+ #ifdef OS_UNIX
459+ if (flock (fileno (s_fp ), LOCK_EX | LOCK_NB ) < 0 ) {
460+ hloge ("flock('%s') error: %d" , g_main_ctx .pidfile , errno );
461+ fclose (s_fp );
462+ s_fp = NULL ;
463+ return -1 ;
464+ }
465+ ftruncate (fileno (s_fp ), 0 );
466+ #else
467+ chsize (fileno (s_fp ), 0 );
468+ #endif
438469 g_main_ctx .pid = hv_getpid ();
439- fprintf (fp , "%d\n" , (int )g_main_ctx .pid );
440- fclose ( fp );
470+ fprintf (s_fp , "%d\n" , (int )g_main_ctx .pid );
471+ fflush ( s_fp );
441472 hlogi ("create_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
442473 atexit (delete_pidfile );
443474 return 0 ;
444475}
445476
446477void delete_pidfile (void ) {
478+ if (s_fp == NULL ) return ;
447479 hlogi ("delete_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
480+ #ifdef OS_UNIX
481+ flock (fileno (s_fp ), LOCK_UN );
482+ #endif
483+ fclose (s_fp );
484+ s_fp = NULL ;
448485 remove (g_main_ctx .pidfile );
449486}
450487
@@ -637,7 +674,7 @@ void signal_handle(const char* signal) {
637674 if (g_main_ctx .oldpid > 0 ) {
638675 printf ("%s start/running, pid=%d\n" , g_main_ctx .program_name , g_main_ctx .oldpid );
639676 } else {
640- printf ("%s stop/waiting \n" , g_main_ctx .program_name );
677+ printf ("%s is already stopped \n" , g_main_ctx .program_name );
641678 }
642679 exit (0 );
643680 } else if (strcmp (signal , "reload" ) == 0 ) {
@@ -648,8 +685,10 @@ void signal_handle(const char* signal) {
648685#else
649686 SetEvent (s_hEventReload );
650687#endif
688+ hv_sleep (1 );
689+ } else {
690+ printf ("%s is already stopped\n" , g_main_ctx .program_name );
651691 }
652- hv_sleep (1 );
653692 exit (0 );
654693 } else {
655694 printf ("Invalid signal: '%s'\n" , signal );
0 commit comments