#define OUTDELTADIR "drpms/"
-// Global variables used by the signal handler failure_exit_cleanup
-char *global_lock_dir = NULL; // Path to .repodata/ dir that is used as a lock
-char *global_tmp_out_repo = NULL; // Path to tmpreodata directory, if NULL
- // than it is same as the global_lock_dir
-
-/** Clean up function called on normal program termination.
- * It removes temporary .repodata/ directory that servers as a lock
- * for other createrepo[_c] processes.
- * This functions acts only if exit status isn't EXIST_SUCCESS.
- *
- * @param exit_status Status
- * @param data User data (unused)
- */
-static void
-failure_exit_cleanup(int exit_status, void *data)
-{
- CR_UNUSED(data);
- if (exit_status != EXIT_SUCCESS) {
- if (global_lock_dir) {
- g_debug("Removing %s", global_lock_dir);
- cr_remove_dir(global_lock_dir, NULL);
- }
-
- if (global_tmp_out_repo) {
- g_debug("Removing %s", global_tmp_out_repo);
- cr_remove_dir(global_tmp_out_repo, NULL);
- }
- }
-}
-
-
-/** Signal handler
- * @param sig Signal number
- */
-static void
-sigint_catcher(int sig)
-{
- CR_UNUSED(sig);
- g_message("SIGINT catched: Terminating...");
- exit(1);
-}
-
-
// TODO: Pass only exlude_masks list here
/** Check if the filename is excluded by any exlude mask.
* @param filename Filename (basename).
}
-
/** Function used to sort pool tasks.
* This function is responsible for order of packages in metadata.
*
gchar *out_repo = NULL; // path/to/out_repo/repodata/
gchar *tmp_out_repo = NULL; // usually path/to/out_repo/.repodata/
gchar *lock_dir = NULL; // path/to/out_repo/.repodata/
- int lock_dir_is_tmp_out_repo = 1;
if (cmd_options->basedir && !g_str_has_prefix(argv[1], "/")) {
gchar *tmp = cr_normalize_dir_path(argv[1]);
// Prepare cachedir for checksum if --cachedir is used
-
if (!prepare_cache_dir(cmd_options, out_dir, &tmp_err)) {
g_printerr("%s\n", tmp_err->message);
g_error_free(tmp_err);
}
// Block signals that terminates the process
-
if (!cr_block_terminating_signals(&tmp_err)) {
g_printerr("%s\n", tmp_err->message);
exit(EXIT_FAILURE);
}
// Check if lock exists & Create lock dir
-
ret = cr_lock_repo(out_dir, cmd_options->ignore_lock, &lock_dir, &tmp_out_repo, &tmp_err);
- global_lock_dir = lock_dir;
if (!ret) {
g_printerr("%s\n", tmp_err->message);
exit(EXIT_FAILURE);
}
- if (g_strcmp0(lock_dir, tmp_out_repo)) {
- global_tmp_out_repo = tmp_out_repo;
- lock_dir_is_tmp_out_repo = 0;
+ // Setup cleanup handlers
+ if (!cr_set_cleanup_handler(lock_dir, tmp_out_repo, &tmp_err)) {
+ g_printerr("%s\n", tmp_err->message);
+ exit(EXIT_FAILURE);
}
-
- // Register cleanup function
- if (on_exit(failure_exit_cleanup, NULL))
- g_warning("Cannot set exit cleanup function by atexit()");
-
- // Set handler that call exit(EXIT_FAILURE) for signals that leads to
- // process termination (list obtained from the "man 7 signal")
- // Signals that are ignored (SIGCHILD) or lead just to stop (SIGSTOP, ..)
- // SHOULDN'T GET THIS HANDLER - these signals do not terminate the process!
-
- g_debug("Signal handler setup");
- struct sigaction sigact;
- sigact.sa_handler = sigint_catcher;
- sigemptyset(&sigact.sa_mask);
- sigact.sa_flags = 0;
-
- // Signals that terminate (from the POSIX.1-1990)
- sigaction(SIGHUP, &sigact, NULL);
- sigaction(SIGINT, &sigact, NULL);
- sigaction(SIGPIPE, &sigact, NULL);
- sigaction(SIGALRM, &sigact, NULL);
- sigaction(SIGTERM, &sigact, NULL);
- sigaction(SIGUSR1, &sigact, NULL);
- sigaction(SIGUSR2, &sigact, NULL);
- // Signals that terminate (from the POSIX.1-2001)
- sigaction(SIGPOLL, &sigact, NULL);
- sigaction(SIGPROF, &sigact, NULL);
- sigaction(SIGVTALRM, &sigact, NULL);
-
-
// Unblock the blocked signals
-
if (!cr_unblock_terminating_signals(&tmp_err)) {
g_printerr("%s\n", tmp_err->message);
exit(EXIT_FAILURE);
}
-
// Open package list
-
FILE *output_pkg_list = NULL;
if (cmd_options->read_pkgs_list) {
output_pkg_list = fopen(cmd_options->read_pkgs_list, "w");
}
// Remove lock
- if (!lock_dir_is_tmp_out_repo)
+ if (g_strcmp0(lock_dir, tmp_out_repo))
+ // If lock_dir is not same as temporary repo dir then remove it
cr_remove_dir(lock_dir, NULL);
// Disable path stored for exit handler
- global_lock_dir = NULL;
- global_tmp_out_repo = NULL;
+ cr_unset_cleanup_handler(NULL);
sigprocmask(SIG_SETMASK, &old_mask, NULL);
#include <glib.h>
#include <glib/gstdio.h>
+#include <stdlib.h>
+#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
#include "misc.h"
#include "cleanup.h"
+
+char *global_lock_dir = NULL; // Path to .repodata/ dir that is used as a lock
+char *global_tmp_out_repo = NULL; // Path to temporary repodata directory,
+ // if NULL that it's same as
+ // the global_lock_dir
+
+/**
+ * Clean up function called on normal program termination.
+ * It removes temporary .repodata/ directory that servers as a lock
+ * for other createrepo[_c] processes.
+ * This functions acts only if exit status != EXIST_SUCCESS.
+ *
+ * @param exit_status Status
+ * @param data User data (unused)
+ */
+static void
+failure_exit_cleanup(int exit_status, void *data)
+{
+ CR_UNUSED(data);
+ if (exit_status != EXIT_SUCCESS) {
+ if (global_lock_dir) {
+ g_debug("Removing %s", global_lock_dir);
+ cr_remove_dir(global_lock_dir, NULL);
+ }
+
+ if (global_tmp_out_repo) {
+ g_debug("Removing %s", global_tmp_out_repo);
+ cr_remove_dir(global_tmp_out_repo, NULL);
+ }
+ }
+}
+
+/** Signal handler
+ * @param sig Signal number
+ */
+static void
+sigint_catcher(int sig)
+{
+ g_message("%s catched: Terminating...", strsignal(sig));
+ exit(1);
+}
+
+gboolean
+cr_set_cleanup_handler(const char *lock_dir,
+ const char *tmp_out_repo,
+ GError **err)
+{
+ CR_UNUSED(err);
+
+ assert(!err || *err == NULL);
+
+ // Set global variables
+ global_lock_dir = g_strdup(lock_dir);
+ global_tmp_out_repo = g_strdup(tmp_out_repo);
+
+ // Register on exit cleanup function
+ if (on_exit(failure_exit_cleanup, NULL))
+ g_warning("Cannot set exit cleanup function by atexit()");
+
+ // Prepare signal handler configuration
+ g_debug("Signal handler setup");
+ struct sigaction sigact;
+ sigact.sa_handler = sigint_catcher;
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = 0;
+
+ // Handle signals that terminate (from the POSIX.1-1990)
+ sigaction(SIGHUP, &sigact, NULL);
+ sigaction(SIGINT, &sigact, NULL);
+ sigaction(SIGPIPE, &sigact, NULL);
+ sigaction(SIGALRM, &sigact, NULL);
+ sigaction(SIGTERM, &sigact, NULL);
+ sigaction(SIGUSR1, &sigact, NULL);
+ sigaction(SIGUSR2, &sigact, NULL);
+
+ // Handle signals that terminate (from the POSIX.1-2001)
+ sigaction(SIGPOLL, &sigact, NULL);
+ sigaction(SIGPROF, &sigact, NULL);
+ sigaction(SIGVTALRM, &sigact, NULL);
+
+ return TRUE;
+}
+
+gboolean
+cr_unset_cleanup_handler(GError **err)
+{
+ CR_UNUSED(err);
+
+ g_free(global_lock_dir);
+ global_lock_dir = NULL;
+ g_free(global_tmp_out_repo);
+ global_tmp_out_repo = NULL;
+
+ return TRUE;
+}
+
gboolean
cr_block_terminating_signals(GError **err)
{
return TRUE;
}
+
* @{
*/
+
+/**
+ * This function does:
+ * 1) Sets on_exit cleanup function that removes temporary directories
+ * 2) Sets a signal handler for signals that lead to process temination.
+ * (List obtained from the "man 7 signal")
+ * Signals that are ignored (SIGCHILD) or lead just to stop (SIGSTOP, ...)
+ * don't get this handler - these signals do not terminate the process!
+ * This handler assures that the cleanup function that is hooked on exit
+ * gets called.
+ *
+ * @param lock_dir Dir that serves as lock (".repodata/")
+ * @param tmp_out_repo Dir that is really used for repodata generation
+ * (usually exactly the same as lock dir if not
+ * --ignore-lock is specified). Could be NULL.
+ * @return TRUE on success, FALSE if err is set.
+ */
+gboolean
+cr_set_cleanup_handler(const char *lock_dir,
+ const char *tmp_out_repo,
+ GError **err);
+
/**
* Block process terminating signals.
* (Useful for creating pseudo-atomic sections in code)
* If FALSE is returned, the content of this variable
* is undefined.
* @param err GError **
- * @return FALSE if err is set, TRUE otherwise.
+ * @return TRUE on success, FALSE if err is set.
*/
gboolean
cr_lock_repo(const gchar *repo_dir,
gchar **lock_dir,
gchar **tmp_repodata_dir,
GError **err);
-// TODO XXX
+
+/**
+ * Unset cleanup handler.
+ * @param err GError **
+ * @return TRUE on success, FALSE if err is set.
+ */
+gboolean
+cr_unset_cleanup_handler(GError **err);
/** @} */