From 2e043aae36bdb8a7591646db00a95dd21f1f368f Mon Sep 17 00:00:00 2001 From: Xavier Chantry Date: Wed, 8 Jul 2009 11:08:32 +0200 Subject: Run ldconfig inside chroot. This fixes FS#15294. The code to run a command inside a chroot was refactored from the _alpm_runscriptlet function to _alpm_run_chroot. Signed-off-by: Xavier Chantry --- lib/libalpm/add.c | 1 - lib/libalpm/remove.c | 1 - lib/libalpm/trans.c | 88 +------------------------------------------ lib/libalpm/util.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++-- lib/libalpm/util.h | 1 + 5 files changed, 102 insertions(+), 92 deletions(-) (limited to 'lib/libalpm') diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 451a6295..4bd52dea 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -888,7 +888,6 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) } /* run ldconfig if it exists */ - _alpm_log(PM_LOG_DEBUG, "running \"ldconfig -r %s\"\n", handle->root); _alpm_ldconfig(handle->root); return(0); diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c index fdf8cce1..d31bf310 100644 --- a/lib/libalpm/remove.c +++ b/lib/libalpm/remove.c @@ -404,7 +404,6 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db) /* run ldconfig if it exists */ if(trans->type != PM_TRANS_TYPE_REMOVEUPGRADE) { - _alpm_log(PM_LOG_DEBUG, "running \"ldconfig -r %s\"\n", handle->root); _alpm_ldconfig(handle->root); } diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index bf4a3ebf..d1c0e930 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -437,11 +436,8 @@ int _alpm_runscriptlet(const char *root, const char *installfn, char scriptfn[PATH_MAX]; char cmdline[PATH_MAX]; char tmpdir[PATH_MAX]; - char cwd[PATH_MAX]; char *scriptpath; - pid_t pid; int clean_tmpdir = 0; - int restore_cwd = 0; int retval = 0; ALPM_LOG_FUNC; @@ -489,21 +485,6 @@ int _alpm_runscriptlet(const char *root, const char *installfn, goto cleanup; } - /* save the cwd so we can restore it later */ - if(getcwd(cwd, PATH_MAX) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); - } else { - restore_cwd = 1; - } - - /* just in case our cwd was removed in the upgrade operation */ - if(chdir(root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), root, strerror(errno)); - goto cleanup; - } - - _alpm_log(PM_LOG_DEBUG, "executing %s script...\n", script); - if(oldver) { snprintf(cmdline, PATH_MAX, ". %s; %s %s %s", scriptpath, script, ver, oldver); @@ -511,80 +492,13 @@ int _alpm_runscriptlet(const char *root, const char *installfn, snprintf(cmdline, PATH_MAX, ". %s; %s %s", scriptpath, script, ver); } - _alpm_log(PM_LOG_DEBUG, "%s\n", cmdline); - /* Flush open fds before fork() to avoid cloning buffers */ - fflush(NULL); - - /* fork- parent and child each have seperate code blocks below */ - pid = fork(); - if(pid == -1) { - _alpm_log(PM_LOG_ERROR, _("could not fork a new process (%s)\n"), strerror(errno)); - retval = 1; - goto cleanup; - } - - if(pid == 0) { - FILE *pipe; - /* this code runs for the child only (the actual chroot/exec) */ - _alpm_log(PM_LOG_DEBUG, "chrooting in %s\n", root); - if(chroot(root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change the root directory (%s)\n"), - strerror(errno)); - exit(1); - } - if(chdir("/") != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to / (%s)\n"), - strerror(errno)); - exit(1); - } - umask(0022); - _alpm_log(PM_LOG_DEBUG, "executing \"%s\"\n", cmdline); - /* execl("/bin/sh", "sh", "-c", cmdline, (char *)NULL); */ - pipe = popen(cmdline, "r"); - if(!pipe) { - _alpm_log(PM_LOG_ERROR, _("call to popen failed (%s)"), - strerror(errno)); - exit(1); - } - while(!feof(pipe)) { - char line[PATH_MAX]; - if(fgets(line, PATH_MAX, pipe) == NULL) - break; - alpm_logaction("%s", line); - EVENT(trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL); - } - retval = pclose(pipe); - exit(WEXITSTATUS(retval)); - } else { - /* this code runs for the parent only (wait on the child) */ - pid_t retpid; - int status; - while((retpid = waitpid(pid, &status, 0)) == -1 && errno == EINTR); - if(retpid == -1) { - _alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)\n"), - strerror(errno)); - retval = 1; - goto cleanup; - } else { - /* check the return status, make sure it is 0 (success) */ - if(WIFEXITED(status)) { - _alpm_log(PM_LOG_DEBUG, "call to waitpid succeeded\n"); - if(WEXITSTATUS(status) != 0) { - _alpm_log(PM_LOG_ERROR, _("scriptlet failed to execute correctly\n")); - retval = 1; - } - } - } - } + retval = _alpm_run_chroot(root, cmdline); cleanup: if(clean_tmpdir && _alpm_rmrf(tmpdir)) { _alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s\n"), tmpdir); } - if(restore_cwd) { - chdir(cwd); - } return(retval); } diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 75f863ab..e56efb17 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -37,6 +37,7 @@ #include #include #include +#include /* libarchive */ #include @@ -49,6 +50,7 @@ #include "alpm.h" #include "alpm_list.h" #include "md5.h" +#include "handle.h" #ifndef HAVE_STRSEP /* This is a replacement for strsep which is not portable (missing on Solaris). @@ -455,17 +457,112 @@ int _alpm_logaction(unsigned short usesyslog, FILE *f, return(ret); } +int _alpm_run_chroot(const char *root, const char *cmd) +{ + char cwd[PATH_MAX]; + pid_t pid; + int restore_cwd = 0; + int retval = 0; + + ALPM_LOG_FUNC; + + /* save the cwd so we can restore it later */ + if(getcwd(cwd, PATH_MAX) == NULL) { + _alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); + } else { + restore_cwd = 1; + } + + /* just in case our cwd was removed in the upgrade operation */ + if(chdir(root) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), root, strerror(errno)); + goto cleanup; + } + + _alpm_log(PM_LOG_DEBUG, "executing \"%s\" under chroot \"%s\"\n", cmd, root); + + /* Flush open fds before fork() to avoid cloning buffers */ + fflush(NULL); + + /* fork- parent and child each have seperate code blocks below */ + pid = fork(); + if(pid == -1) { + _alpm_log(PM_LOG_ERROR, _("could not fork a new process (%s)\n"), strerror(errno)); + retval = 1; + goto cleanup; + } + + if(pid == 0) { + FILE *pipe; + /* this code runs for the child only (the actual chroot/exec) */ + _alpm_log(PM_LOG_DEBUG, "chrooting in %s\n", root); + if(chroot(root) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change the root directory (%s)\n"), + strerror(errno)); + exit(1); + } + if(chdir("/") != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to / (%s)\n"), + strerror(errno)); + exit(1); + } + umask(0022); + pipe = popen(cmd, "r"); + if(!pipe) { + _alpm_log(PM_LOG_ERROR, _("call to popen failed (%s)"), + strerror(errno)); + exit(1); + } + while(!feof(pipe)) { + char line[PATH_MAX]; + if(fgets(line, PATH_MAX, pipe) == NULL) + break; + alpm_logaction("%s", line); + EVENT(handle->trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL); + } + retval = pclose(pipe); + exit(WEXITSTATUS(retval)); + } else { + /* this code runs for the parent only (wait on the child) */ + pid_t retpid; + int status; + while((retpid = waitpid(pid, &status, 0)) == -1 && errno == EINTR); + if(retpid == -1) { + _alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)\n"), + strerror(errno)); + retval = 1; + goto cleanup; + } else { + /* check the return status, make sure it is 0 (success) */ + if(WIFEXITED(status)) { + _alpm_log(PM_LOG_DEBUG, "call to waitpid succeeded\n"); + if(WEXITSTATUS(status) != 0) { + _alpm_log(PM_LOG_ERROR, _("command failed to execute correctly\n")); + retval = 1; + } + } + } + } + +cleanup: + if(restore_cwd) { + chdir(cwd); + } + + return(retval); +} + int _alpm_ldconfig(const char *root) { char line[PATH_MAX]; + _alpm_log(PM_LOG_DEBUG, "running ldconfig\n"); + snprintf(line, PATH_MAX, "%setc/ld.so.conf", root); if(access(line, F_OK) == 0) { snprintf(line, PATH_MAX, "%ssbin/ldconfig", root); if(access(line, X_OK) == 0) { - char cmd[PATH_MAX]; - snprintf(cmd, PATH_MAX, "%s -r %s", line, root); - system(cmd); + _alpm_run_chroot(root, "ldconfig"); } } diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index e2d44740..4bc8b92f 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -66,6 +66,7 @@ int _alpm_lckrm(); int _alpm_unpack(const char *archive, const char *prefix, const char *fn); int _alpm_rmrf(const char *path); int _alpm_logaction(unsigned short usesyslog, FILE *f, const char *fmt, va_list args); +int _alpm_run_chroot(const char *root, const char *cmd); int _alpm_ldconfig(const char *root); int _alpm_str_cmp(const void *s1, const void *s2); char *_alpm_filecache_find(const char *filename); -- cgit v1.2.3