Skip to content

Commit e8b593a

Browse files
committed
fix main_ctx_init misjudging oldpid running in special cases
support main_ctx_init custom set run_dir
1 parent 3778046 commit e8b593a

File tree

1 file changed

+50
-13
lines changed

1 file changed

+50
-13
lines changed

base/hmain.c

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
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+
1420
main_ctx_t g_main_ctx;
1521
printf_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

432453
int 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

447478
void 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

Comments
 (0)