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,40 @@ 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+ const int fd = fileno (s_fp );
460+ #ifdef OS_UNIX
461+ fcntl (fd , F_SETFD , fcntl (fd , F_GETFD ) | FD_CLOEXEC );
462+ if (flock (fd , LOCK_EX | LOCK_NB ) < 0 ) {
463+ hloge ("flock('%s') error: %d" , g_main_ctx .pidfile , errno );
464+ fclose (s_fp );
465+ s_fp = NULL ;
466+ return -1 ;
467+ }
468+ ftruncate (fd , 0 );
469+ #else
470+ chsize (fd , 0 );
471+ #endif
439472 g_main_ctx .pid = hv_getpid ();
440- fprintf (fp , "%d\n" , (int )g_main_ctx .pid );
441- fclose ( fp );
473+ fprintf (s_fp , "%d\n" , (int )g_main_ctx .pid );
474+ fflush ( s_fp );
442475 hlogi ("create_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
443476 atexit (delete_pidfile );
444477 return 0 ;
445478}
446479
447480void delete_pidfile (void ) {
481+ if (s_fp == NULL ) return ;
448482 hlogi ("delete_pidfile('%s') pid=%d" , g_main_ctx .pidfile , g_main_ctx .pid );
483+ #ifdef OS_UNIX
484+ flock (fileno (s_fp ), LOCK_UN );
485+ #endif
486+ fclose (s_fp );
487+ s_fp = NULL ;
449488 remove (g_main_ctx .pidfile );
450489}
451490
0 commit comments