|
|
|
@ -29,6 +29,7 @@
|
|
|
|
# include <unistd.h>
|
|
|
|
# include <unistd.h>
|
|
|
|
# include <signal.h>
|
|
|
|
# include <signal.h>
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __APPLE__
|
|
|
|
#ifdef __APPLE__
|
|
|
|
# import <sys/sysctl.h>
|
|
|
|
# import <sys/sysctl.h>
|
|
|
|
@ -98,7 +99,7 @@ string loadCustomTemplate (string customIndexPath) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
volatile sig_atomic_t waiting = false;
|
|
|
|
volatile sig_atomic_t waiting = false;
|
|
|
|
volatile sig_atomic_t library_reload_requested = false;
|
|
|
|
volatile sig_atomic_t libraryMustBeReloaded = false;
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
#ifndef _WIN32
|
|
|
|
void handle_sigterm(int signum)
|
|
|
|
void handle_sigterm(int signum)
|
|
|
|
@ -111,7 +112,7 @@ void handle_sigterm(int signum)
|
|
|
|
|
|
|
|
|
|
|
|
void handle_sighup(int signum)
|
|
|
|
void handle_sighup(int signum)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
library_reload_requested = true;
|
|
|
|
libraryMustBeReloaded = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
typedef void (*SignalHandler)(int);
|
|
|
|
typedef void (*SignalHandler)(int);
|
|
|
|
@ -132,6 +133,31 @@ void setup_sighandlers()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t fileModificationTime(const std::string& path)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#if defined(_WIN32)
|
|
|
|
|
|
|
|
#define stat _stat
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
struct stat fileStatData;
|
|
|
|
|
|
|
|
if ( stat(path.c_str(), &fileStatData) == 0 ) {
|
|
|
|
|
|
|
|
return fileStatData.st_mtime;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
#undef stat
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t newestFileTimestamp(const std::vector<std::string>& paths)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
uint64_t t = 0;
|
|
|
|
|
|
|
|
for ( const auto& p : paths ) {
|
|
|
|
|
|
|
|
t = std::max(t, fileModificationTime(p));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return t;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool reloadLibrary(kiwix::Manager& mgr, const std::vector<std::string>& paths)
|
|
|
|
bool reloadLibrary(kiwix::Manager& mgr, const std::vector<std::string>& paths)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
@ -172,6 +198,7 @@ int main(int argc, char** argv)
|
|
|
|
bool noDateAliasesFlag = false;
|
|
|
|
bool noDateAliasesFlag = false;
|
|
|
|
bool blockExternalLinks = false;
|
|
|
|
bool blockExternalLinks = false;
|
|
|
|
bool isVerboseFlag = false;
|
|
|
|
bool isVerboseFlag = false;
|
|
|
|
|
|
|
|
bool monitorLibrary = false;
|
|
|
|
unsigned int PPID = 0;
|
|
|
|
unsigned int PPID = 0;
|
|
|
|
|
|
|
|
|
|
|
|
static struct option long_options[]
|
|
|
|
static struct option long_options[]
|
|
|
|
@ -189,13 +216,14 @@ int main(int argc, char** argv)
|
|
|
|
{"threads", required_argument, 0, 't'},
|
|
|
|
{"threads", required_argument, 0, 't'},
|
|
|
|
{"urlRootLocation", required_argument, 0, 'r'},
|
|
|
|
{"urlRootLocation", required_argument, 0, 'r'},
|
|
|
|
{"customIndex", required_argument, 0, 'c'},
|
|
|
|
{"customIndex", required_argument, 0, 'c'},
|
|
|
|
|
|
|
|
{"monitorLibrary", no_argument, 0, 'M'},
|
|
|
|
{0, 0, 0, 0}};
|
|
|
|
{0, 0, 0, 0}};
|
|
|
|
|
|
|
|
|
|
|
|
/* Argument parsing */
|
|
|
|
/* Argument parsing */
|
|
|
|
while (true) {
|
|
|
|
while (true) {
|
|
|
|
int option_index = 0;
|
|
|
|
int option_index = 0;
|
|
|
|
int c
|
|
|
|
int c
|
|
|
|
= getopt_long(argc, argv, "zmnbdvVla:p:f:t:r:i:c:", long_options, &option_index);
|
|
|
|
= getopt_long(argc, argv, "zmnbdvVla:p:f:t:r:i:c:M", long_options, &option_index);
|
|
|
|
|
|
|
|
|
|
|
|
if (c != -1) {
|
|
|
|
if (c != -1) {
|
|
|
|
switch (c) {
|
|
|
|
switch (c) {
|
|
|
|
@ -241,6 +269,9 @@ int main(int argc, char** argv)
|
|
|
|
case 'c':
|
|
|
|
case 'c':
|
|
|
|
customIndexPath = string(optarg);
|
|
|
|
customIndexPath = string(optarg);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'M':
|
|
|
|
|
|
|
|
monitorLibrary = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (optind < argc) {
|
|
|
|
if (optind < argc) {
|
|
|
|
@ -285,6 +316,8 @@ int main(int argc, char** argv)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto libraryFileTimestamp = newestFileTimestamp(libraryPaths);
|
|
|
|
|
|
|
|
auto curLibraryFileTimestamp = libraryFileTimestamp;
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
#ifndef _WIN32
|
|
|
|
/* Fork if necessary */
|
|
|
|
/* Fork if necessary */
|
|
|
|
@ -361,10 +394,17 @@ int main(int argc, char** argv)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
kiwix::sleep(1000);
|
|
|
|
kiwix::sleep(1000);
|
|
|
|
if ( library_reload_requested && !libraryPaths.empty() ) {
|
|
|
|
|
|
|
|
|
|
|
|
if ( monitorLibrary ) {
|
|
|
|
|
|
|
|
curLibraryFileTimestamp = newestFileTimestamp(libraryPaths);
|
|
|
|
|
|
|
|
libraryMustBeReloaded += curLibraryFileTimestamp > libraryFileTimestamp;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( libraryMustBeReloaded && !libraryPaths.empty() ) {
|
|
|
|
|
|
|
|
libraryFileTimestamp = curLibraryFileTimestamp;
|
|
|
|
reloadLibrary(manager, libraryPaths);
|
|
|
|
reloadLibrary(manager, libraryPaths);
|
|
|
|
nameMapper.update();
|
|
|
|
nameMapper.update();
|
|
|
|
library_reload_requested = false;
|
|
|
|
libraryMustBeReloaded = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (waiting);
|
|
|
|
} while (waiting);
|
|
|
|
|
|
|
|
|
|
|
|
|