summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorXavier Chantry <shiningxc@gmail.com>2009-07-08 11:08:32 +0200
committerDan McGee <dan@archlinux.org>2009-07-16 13:12:04 +0200
commit2e043aae36bdb8a7591646db00a95dd21f1f368f (patch)
tree6bc63b3cb042e310aa21d6991cfdaff589fa5f14 /lib
parent41a55d4effecfb2914e96ed4a99eb621557c6d2f (diff)
downloadpacman-2e043aae36bdb8a7591646db00a95dd21f1f368f.tar.gz
pacman-2e043aae36bdb8a7591646db00a95dd21f1f368f.tar.xz
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 <shiningxc@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/libalpm/add.c1
-rw-r--r--lib/libalpm/remove.c1
-rw-r--r--lib/libalpm/trans.c88
-rw-r--r--lib/libalpm/util.c103
-rw-r--r--lib/libalpm/util.h1
5 files changed, 102 insertions, 92 deletions
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 <stdio.h>
#include <string.h>
#include <unistd.h>
-#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
@@ -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 <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/wait.h>
/* libarchive */
#include <archive.h>
@@ -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);