From c146215178d446fe676d9beebd0409132e83049b Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 17 Jul 2022 13:12:18 +0100 Subject: [PATCH] prefork: Move garbage handling back cgi-fcgi-interp prefork-interp wants to do this differently. Signed-off-by: Ian Jackson --- cprogs/cgi-fcgi-interp.c | 101 +++++++++++++++++++++++++++++++++++++++ cprogs/prefork.c | 100 -------------------------------------- cprogs/prefork.h | 7 --- 3 files changed, 101 insertions(+), 107 deletions(-) diff --git a/cprogs/cgi-fcgi-interp.c b/cprogs/cgi-fcgi-interp.c index 1c160e2..7ed5625 100644 --- a/cprogs/cgi-fcgi-interp.c +++ b/cprogs/cgi-fcgi-interp.c @@ -135,6 +135,9 @@ static const char *stage2; const char our_name[] = "cgi-fcgi-interp"; +static int numservers=4, debugmode; +static int check_interval=300; + const struct cmdinfo cmdinfos[]= { { "help", 0, .call=of_help }, { 0, 'g', 1, .sassignto= &ident }, @@ -165,6 +168,104 @@ static void prep_stage2(void) { if (r) diee("set %s (to announce to stage2)", STAGE2_VAR); } +#ifdef st_mtime + +static bool stab_isnewer(const struct stat *a, const struct stat *b) { + if (debugmode) + fprintf(stderr,"stab_isnewer mtim %lu.%06lu %lu.06%lu\n", + (unsigned long)a->st_mtim.tv_sec, + (unsigned long)a->st_mtim.tv_nsec, + (unsigned long)b->st_mtim.tv_sec, + (unsigned long)b->st_mtim.tv_nsec); + return timespeccmp(&a->st_mtim, &b->st_mtim, >); +} + +static void stab_mtimenow(struct stat *out) { + int r = clock_gettime(CLOCK_REALTIME, &out->st_mtim); + if (r) diee("(stage2) clock_gettime"); + if (debugmode) + fprintf(stderr,"stab_mtimenow mtim %lu.%06lu\n", + (unsigned long)out->st_mtim.tv_sec, + (unsigned long)out->st_mtim.tv_nsec); +} + +#else /* !defined(st_mtime) */ + +static bool stab_isnewer(const struct stat *a, const struct stat *b) { + if (debugmode) + fprintf(stderr,"stab_isnewer mtime %lu %lu\n", + (unsigned long)a->st_mtime, + (unsigned long)b->st_mtime); + return a->st_mtime > b->st_mtime; +} + +static void stab_mtimenow(struct stat *out) { + out->st_mtime = time(NULL); + if (out->st_mtime == (time_t)-1) diee("(stage2) time()"); + if (debugmode) + fprintf(stderr,"stab_mtimenow mtime %lu\n", + (unsigned long)out->st_mtime); +} + +#endif /* !defined(st_mtime) */ + +static bool check_garbage_vs(const struct stat *started) { + struct stat script_stab; + int r; + + r = lstat(script, &script_stab); + if (r) diee("lstat script (%s)",script); + + if (stab_isnewer(&script_stab, started)) + return 1; + + if (S_ISLNK(script_stab.st_mode)) { + r = stat(script, &script_stab); + if (r) diee("stat script (%s0",script); + + if (stab_isnewer(&script_stab, started)) + return 1; + } + + return 0; +} + +static bool check_garbage(void) { + struct stat sock_stab; + int r; + + r = lstat(socket_path, &sock_stab); + if (r) { + if ((errno == ENOENT)) + return 0; /* well, no garbage then */ + diee("stat socket (%s)",socket_path); + } + + return check_garbage_vs(&sock_stab); +} + +static void tidy_garbage(void) { + /* We lock l and re-check. The effect of this is that each + * stale socket is removed only once. So unless multiple updates to + * the script happen rapidly, we can't be racing with the cgi-fcgi + * (which is recreating the socket */ + int lockfd = -1; + int r; + + lockfd = acquire_lock(); + + if (check_garbage()) { + r = unlink(socket_path); + if (r) { + if (!(errno == ENOENT)) + diee("remove out-of-date socket (%s)", socket_path); + } + } + + r = close(lockfd); + if (r) diee("close lock (%s)", lock_path); +} + /* stage2 predeclarations */ static void record_baseline_time(void); static void become_pgrp(void); diff --git a/cprogs/prefork.c b/cprogs/prefork.c index 3c6bc6a..095dd44 100644 --- a/cprogs/prefork.c +++ b/cprogs/prefork.c @@ -3,8 +3,6 @@ #include "prefork.h" const char *interp, *ident; -int numservers=4, debugmode; -int check_interval=300; struct sha256_ctx identsc; @@ -180,82 +178,6 @@ void find_socket_path(void) { socket_path = m_asprintf("%s/s%s",run_base,ident); } -#ifdef st_mtime - -bool stab_isnewer(const struct stat *a, const struct stat *b) { - if (debugmode) - fprintf(stderr,"stab_isnewer mtim %lu.%06lu %lu.06%lu\n", - (unsigned long)a->st_mtim.tv_sec, - (unsigned long)a->st_mtim.tv_nsec, - (unsigned long)b->st_mtim.tv_sec, - (unsigned long)b->st_mtim.tv_nsec); - return timespeccmp(&a->st_mtim, &b->st_mtim, >); -} - -void stab_mtimenow(struct stat *out) { - int r = clock_gettime(CLOCK_REALTIME, &out->st_mtim); - if (r) diee("(stage2) clock_gettime"); - if (debugmode) - fprintf(stderr,"stab_mtimenow mtim %lu.%06lu\n", - (unsigned long)out->st_mtim.tv_sec, - (unsigned long)out->st_mtim.tv_nsec); -} - -#else /* !defined(st_mtime) */ - -bool stab_isnewer(const struct stat *a, const struct stat *b) { - if (debugmode) - fprintf(stderr,"stab_isnewer mtime %lu %lu\n", - (unsigned long)a->st_mtime, - (unsigned long)b->st_mtime); - return a->st_mtime > b->st_mtime; -} - -void stab_mtimenow(struct stat *out) { - out->st_mtime = time(NULL); - if (out->st_mtime == (time_t)-1) diee("(stage2) time()"); - if (debugmode) - fprintf(stderr,"stab_mtimenow mtime %lu\n", - (unsigned long)out->st_mtime); -} - -#endif /* !defined(st_mtime) */ - -bool check_garbage_vs(const struct stat *started) { - struct stat script_stab; - int r; - - r = lstat(script, &script_stab); - if (r) diee("lstat script (%s)",script); - - if (stab_isnewer(&script_stab, started)) - return 1; - - if (S_ISLNK(script_stab.st_mode)) { - r = stat(script, &script_stab); - if (r) diee("stat script (%s0",script); - - if (stab_isnewer(&script_stab, started)) - return 1; - } - - return 0; -} - -bool check_garbage(void) { - struct stat sock_stab; - int r; - - r = lstat(socket_path, &sock_stab); - if (r) { - if ((errno == ENOENT)) - return 0; /* well, no garbage then */ - diee("stat socket (%s)",socket_path); - } - - return check_garbage_vs(&sock_stab); -} - // Returns fd int acquire_lock(void) { int r; @@ -272,28 +194,6 @@ int acquire_lock(void) { return lockfd; } -void tidy_garbage(void) { - /* We lock l and re-check. The effect of this is that each - * stale socket is removed only once. So unless multiple updates to - * the script happen rapidly, we can't be racing with the cgi-fcgi - * (which is recreating the socket */ - int lockfd = -1; - int r; - - lockfd = acquire_lock(); - - if (check_garbage()) { - r = unlink(socket_path); - if (r) { - if (!(errno == ENOENT)) - diee("remove out-of-date socket (%s)", socket_path); - } - } - - r = close(lockfd); - if (r) diee("close lock (%s)", lock_path); -} - static void shbang_opts(const char *const **argv_io, const struct cmdinfo *cmdinfos) { myopt(argv_io, cmdinfos); diff --git a/cprogs/prefork.h b/cprogs/prefork.h index 895a9de..1d69afc 100644 --- a/cprogs/prefork.h +++ b/cprogs/prefork.h @@ -35,8 +35,6 @@ #define MINHEXHASH 33 extern const char *interp, *ident; -extern int numservers, debugmode; -extern int check_interval; extern struct sha256_ctx identsc; @@ -50,12 +48,7 @@ extern bool logging; bool find_run_base_var_run(void); void find_socket_path(void); -bool stab_isnewer(const struct stat *a, const struct stat *b); -void stab_mtimenow(struct stat *out); int acquire_lock(void); -bool check_garbage_vs(const struct stat *started); -bool check_garbage(void); -void tidy_garbage(void); extern const struct cmdinfo cmdinfos[]; -- 2.30.2