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 ;
1521printf_t printf_fn = printf ;
1622
@@ -74,7 +80,7 @@ int main_ctx_init(int argc, char** argv) {
7480 get_executable_path (argv [0 ], MAX_PATH );
7581 }
7682
77- get_run_dir (g_main_ctx .run_dir , sizeof (g_main_ctx .run_dir ));
83+ if (! hv_exists ( g_main_ctx . run_dir )) get_run_dir (g_main_ctx .run_dir , sizeof (g_main_ctx .run_dir ));
7884 //printf("run_dir=%s\n", g_main_ctx.run_dir);
7985 strncpy (g_main_ctx .program_name , hv_basename (argv [0 ]), sizeof (g_main_ctx .program_name ));
8086#ifdef OS_WIN
@@ -90,21 +96,36 @@ int main_ctx_init(int argc, char** argv) {
9096 snprintf (g_main_ctx .pidfile , sizeof (g_main_ctx .pidfile ), "%s/logs/%s.pid" , g_main_ctx .run_dir , g_main_ctx .program_name );
9197 snprintf (g_main_ctx .logfile , sizeof (g_main_ctx .logfile ), "%s/logs/%s.log" , g_main_ctx .run_dir , g_main_ctx .program_name );
9298 hlog_set_file (g_main_ctx .logfile );
93-
99+ #ifdef OS_WIN
100+ // Only Windows does not allow deleting occupied files
101+ remove (g_main_ctx .pidfile );
102+ #endif
94103 g_main_ctx .pid = getpid ();
95104 g_main_ctx .oldpid = getpid_from_pidfile ();
96105#ifdef OS_UNIX
97- if (kill (g_main_ctx .oldpid , 0 ) == -1 && errno == ESRCH ) {
98- g_main_ctx .oldpid = -1 ;
106+ s_fp = fopen (g_main_ctx .pidfile , "a" );
107+ if (s_fp != NULL ) {
108+ if (flock (fileno (s_fp ), LOCK_EX | LOCK_NB ) == 0 ) {
109+ // The lock is successful, indicating that oldpid has ended
110+ g_main_ctx .oldpid = -1 ;
111+ flock (fileno (s_fp ), LOCK_UN );
112+ }
113+ fclose (s_fp );
114+ s_fp = NULL ;
99115 }
100- #else
101- HANDLE hproc = OpenProcess (PROCESS_TERMINATE , FALSE, g_main_ctx .oldpid );
102- if (hproc == NULL ) {
116+ if (kill (g_main_ctx .oldpid , 0 ) == -1 && errno == ESRCH ) {
103117 g_main_ctx .oldpid = -1 ;
104118 }
105- else {
119+ #endif
120+
121+ #ifdef OS_WIN
122+ DWORD exitCode = 0 ;
123+ const HANDLE hproc = OpenProcess (PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION , FALSE, g_main_ctx .oldpid );
124+ if (hproc ) {
125+ GetExitCodeProcess (hproc , & exitCode );
106126 CloseHandle (hproc );
107127 }
128+ if (exitCode != STILL_ACTIVE ) g_main_ctx .oldpid = -1 ;
108129#endif
109130
110131 // save arg
@@ -430,22 +451,38 @@ void setproctitle(const char* fmt, ...) {
430451#endif
431452
432453int create_pidfile () {
433- FILE * fp = fopen (g_main_ctx .pidfile , "w " );
434- if (fp == NULL ) {
454+ s_fp = fopen (g_main_ctx .pidfile , "a " );
455+ if (s_fp == NULL ) {
435456 hloge ("fopen('%s') error: %d" , g_main_ctx .pidfile , errno );
436457 return -1 ;
437458 }
438-
459+ #ifdef OS_UNIX
460+ if (flock (fileno (s_fp ), LOCK_EX | LOCK_NB ) < 0 ) {
461+ hloge ("flock('%s') error: %d" , g_main_ctx .pidfile , errno );
462+ fclose (s_fp );
463+ s_fp = NULL ;
464+ return -1 ;
465+ }
466+ ftruncate (fileno (s_fp ), 0 );
467+ #else
468+ chsize (fileno (s_fp ), 0 );
469+ #endif
439470 g_main_ctx .pid = hv_getpid ();
440- fprintf (fp , "%d\n" , (int )g_main_ctx .pid );
441- fclose ( fp );
471+ fprintf (s_fp , "%d\n" , (int )g_main_ctx .pid );
472+ fflush ( s_fp );
442473 hlogi ("create_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
443474 atexit (delete_pidfile );
444475 return 0 ;
445476}
446477
447478void delete_pidfile (void ) {
479+ if (s_fp == NULL ) return ;
448480 hlogi ("delete_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
481+ #ifdef OS_UNIX
482+ flock (fileno (s_fp ), LOCK_UN );
483+ #endif
484+ fclose (s_fp );
485+ s_fp = NULL ;
449486 remove (g_main_ctx .pidfile );
450487}
451488
0 commit comments