11
11
#define environ (*_NSGetEnviron())
12
12
#endif
13
13
14
+ #ifdef OS_UNIX
15
+ #include <sys/file.h>
16
+ #endif
17
+
18
+ static FILE * s_fp = NULL ;
19
+
14
20
main_ctx_t g_main_ctx ;
15
21
16
22
static void init_arg_kv (int maxsize ) {
@@ -73,7 +79,7 @@ int main_ctx_init(int argc, char** argv) {
73
79
get_executable_path (argv [0 ], MAX_PATH );
74
80
}
75
81
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 ));
77
83
//printf("run_dir=%s\n", g_main_ctx.run_dir);
78
84
strncpy (g_main_ctx .program_name , hv_basename (argv [0 ]), sizeof (g_main_ctx .program_name ));
79
85
#ifdef OS_WIN
@@ -89,21 +95,36 @@ int main_ctx_init(int argc, char** argv) {
89
95
snprintf (g_main_ctx .pidfile , sizeof (g_main_ctx .pidfile ), "%s/logs/%s.pid" , g_main_ctx .run_dir , g_main_ctx .program_name );
90
96
snprintf (g_main_ctx .logfile , sizeof (g_main_ctx .logfile ), "%s/logs/%s.log" , g_main_ctx .run_dir , g_main_ctx .program_name );
91
97
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
93
102
g_main_ctx .pid = getpid ();
94
103
g_main_ctx .oldpid = getpid_from_pidfile ();
95
104
#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 ;
98
114
}
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 ) {
102
116
g_main_ctx .oldpid = -1 ;
103
117
}
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 );
105
125
CloseHandle (hproc );
106
126
}
127
+ if (exitCode != STILL_ACTIVE ) g_main_ctx .oldpid = -1 ;
107
128
#endif
108
129
109
130
// save arg
@@ -429,22 +450,38 @@ void setproctitle(const char* fmt, ...) {
429
450
#endif
430
451
431
452
int 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 ) {
434
455
hloge ("fopen('%s') error: %d" , g_main_ctx .pidfile , errno );
435
456
return -1 ;
436
457
}
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
438
469
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 );
441
472
hlogi ("create_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
442
473
atexit (delete_pidfile );
443
474
return 0 ;
444
475
}
445
476
446
477
void delete_pidfile (void ) {
478
+ if (s_fp == NULL ) return ;
447
479
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 ;
448
485
remove (g_main_ctx .pidfile );
449
486
}
450
487
@@ -637,7 +674,7 @@ void signal_handle(const char* signal) {
637
674
if (g_main_ctx .oldpid > 0 ) {
638
675
printf ("%s start/running, pid=%d\n" , g_main_ctx .program_name , g_main_ctx .oldpid );
639
676
} else {
640
- printf ("%s stop/waiting \n" , g_main_ctx .program_name );
677
+ printf ("%s is already stopped \n" , g_main_ctx .program_name );
641
678
}
642
679
exit (0 );
643
680
} else if (strcmp (signal , "reload" ) == 0 ) {
@@ -648,8 +685,10 @@ void signal_handle(const char* signal) {
648
685
#else
649
686
SetEvent (s_hEventReload );
650
687
#endif
688
+ hv_sleep (1 );
689
+ } else {
690
+ printf_fn ("%s is already stopped\n" , g_main_ctx .program_name );
651
691
}
652
- hv_sleep (1 );
653
692
exit (0 );
654
693
} else {
655
694
printf ("Invalid signal: '%s'\n" , signal );
0 commit comments