--- programs/mythbackend/housekeeper.cpp.housekeeper 2005-12-27 00:20:47.000000000 -0500 +++ programs/mythbackend/housekeeper.cpp 2006-05-22 23:43:48.000000000 -0400 @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -17,15 +18,10 @@ #include "libmyth/mythcontext.h" #include "libmyth/mythdbcon.h" +#include "libmyth/exitcodes.h" bool HouseKeeper_filldb_running = false; -void reapChild(int /* sig */) -{ - (void)wait(0); - HouseKeeper_filldb_running = false; -} - HouseKeeper::HouseKeeper(bool runthread, bool master) { isMaster = master; @@ -276,6 +272,13 @@ } } +struct housekeep_thread_info { + const char *cmd; + int cmd_started; +}; + +static void *doRunFillDatabase(void *); + void HouseKeeper::runFillDatabase() { QString command; @@ -291,15 +294,94 @@ else command = QString("%1 %2 >>%3 2>&1").arg(mfpath).arg(mfarg).arg(mflog); - signal(SIGCHLD, &reapChild); + pthread_t housekeep_thread; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + struct housekeep_thread_info housekeep_info; + + housekeep_info.cmd=command.ascii(); + housekeep_info.cmd_started=0; + + pthread_create(&housekeep_thread, &attr, doRunFillDatabase, + &housekeep_info); + pthread_attr_destroy(&attr); + + while (!housekeep_info.cmd_started) + { + sleep(1); + } +} + +static void filldb_done(void *) +{ + HouseKeeper_filldb_running = false; +} + +static void *doRunFillDatabase(void *arg) +{ + struct housekeep_thread_info *hinfo= + (struct housekeep_thread_info *)arg; + + pid_t p=fork(); + + if (p < 0) + { + hinfo->cmd_started=1; + + VERBOSE(VB_IMPORTANT, + QString("doRunFillDatabase(): Error, fork() failed because %1") + .arg(strerror(errno))); + return 0; + } + + if (p == 0) + { + for(int i = 3; i < sysconf(_SC_OPEN_MAX) - 1; ++i) + close(i); + + /* Attach stdin to /dev/null */ + int fd = open("/dev/null", O_RDONLY); + dup2(fd, 0); + + if (fd != 0) + close(fd); + + execl("/bin/sh", "sh", "-c", hinfo->cmd, NULL); + if (errno) + { + VERBOSE(VB_IMPORTANT, + QString("doRunFillDatabase(): Error, execl() failed because %1") + .arg(strerror(errno))); + } + _exit(MYTHSYSTEM__EXIT__EXECL_ERROR); + } + HouseKeeper_filldb_running = true; - if (fork() == 0) + + pthread_cleanup_push(filldb_done, NULL); + + hinfo->cmd_started=1; + + int status; + + if (waitpid(p, &status, 0) < 0) { - for(int i = 3; i < sysconf(_SC_OPEN_MAX) - 1; ++i) - close(i); - system(command.ascii()); - _exit(0); // this exit is ok, non-error exit from system command. + VERBOSE(VB_IMPORTANT, + QString("doRunFillDatabase(): Error, waitpid() failed because %1") + .arg(strerror(errno))); } + else if (status != 0) + { + VERBOSE(VB_IMPORTANT, + QString("doRunFillDatabase(): mythfilldatabase terminated with exit code %1") + .arg(status)); + } + + pthread_cleanup_pop(1); + return 0; } void HouseKeeper::CleanupMyOldRecordings(void)