mirror of
https://github.com/moparisthebest/pacman
synced 2024-11-12 04:15:06 -05:00
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>
This commit is contained in:
parent
41a55d4eff
commit
2e043aae36
@ -888,7 +888,6 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* run ldconfig if it exists */
|
/* run ldconfig if it exists */
|
||||||
_alpm_log(PM_LOG_DEBUG, "running \"ldconfig -r %s\"\n", handle->root);
|
|
||||||
_alpm_ldconfig(handle->root);
|
_alpm_ldconfig(handle->root);
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -404,7 +404,6 @@ int _alpm_remove_commit(pmtrans_t *trans, pmdb_t *db)
|
|||||||
|
|
||||||
/* run ldconfig if it exists */
|
/* run ldconfig if it exists */
|
||||||
if(trans->type != PM_TRANS_TYPE_REMOVEUPGRADE) {
|
if(trans->type != PM_TRANS_TYPE_REMOVEUPGRADE) {
|
||||||
_alpm_log(PM_LOG_DEBUG, "running \"ldconfig -r %s\"\n", handle->root);
|
|
||||||
_alpm_ldconfig(handle->root);
|
_alpm_ldconfig(handle->root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
@ -437,11 +436,8 @@ int _alpm_runscriptlet(const char *root, const char *installfn,
|
|||||||
char scriptfn[PATH_MAX];
|
char scriptfn[PATH_MAX];
|
||||||
char cmdline[PATH_MAX];
|
char cmdline[PATH_MAX];
|
||||||
char tmpdir[PATH_MAX];
|
char tmpdir[PATH_MAX];
|
||||||
char cwd[PATH_MAX];
|
|
||||||
char *scriptpath;
|
char *scriptpath;
|
||||||
pid_t pid;
|
|
||||||
int clean_tmpdir = 0;
|
int clean_tmpdir = 0;
|
||||||
int restore_cwd = 0;
|
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
ALPM_LOG_FUNC;
|
ALPM_LOG_FUNC;
|
||||||
@ -489,21 +485,6 @@ int _alpm_runscriptlet(const char *root, const char *installfn,
|
|||||||
goto cleanup;
|
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) {
|
if(oldver) {
|
||||||
snprintf(cmdline, PATH_MAX, ". %s; %s %s %s",
|
snprintf(cmdline, PATH_MAX, ". %s; %s %s %s",
|
||||||
scriptpath, script, ver, oldver);
|
scriptpath, script, ver, oldver);
|
||||||
@ -511,80 +492,13 @@ int _alpm_runscriptlet(const char *root, const char *installfn,
|
|||||||
snprintf(cmdline, PATH_MAX, ". %s; %s %s",
|
snprintf(cmdline, PATH_MAX, ". %s; %s %s",
|
||||||
scriptpath, script, ver);
|
scriptpath, script, ver);
|
||||||
}
|
}
|
||||||
_alpm_log(PM_LOG_DEBUG, "%s\n", cmdline);
|
|
||||||
|
|
||||||
/* Flush open fds before fork() to avoid cloning buffers */
|
retval = _alpm_run_chroot(root, cmdline);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if(clean_tmpdir && _alpm_rmrf(tmpdir)) {
|
if(clean_tmpdir && _alpm_rmrf(tmpdir)) {
|
||||||
_alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s\n"), tmpdir);
|
_alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s\n"), tmpdir);
|
||||||
}
|
}
|
||||||
if(restore_cwd) {
|
|
||||||
chdir(cwd);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(retval);
|
return(retval);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
/* libarchive */
|
/* libarchive */
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
@ -49,6 +50,7 @@
|
|||||||
#include "alpm.h"
|
#include "alpm.h"
|
||||||
#include "alpm_list.h"
|
#include "alpm_list.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
|
#include "handle.h"
|
||||||
|
|
||||||
#ifndef HAVE_STRSEP
|
#ifndef HAVE_STRSEP
|
||||||
/* This is a replacement for strsep which is not portable (missing on Solaris).
|
/* 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);
|
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)
|
int _alpm_ldconfig(const char *root)
|
||||||
{
|
{
|
||||||
char line[PATH_MAX];
|
char line[PATH_MAX];
|
||||||
|
|
||||||
|
_alpm_log(PM_LOG_DEBUG, "running ldconfig\n");
|
||||||
|
|
||||||
snprintf(line, PATH_MAX, "%setc/ld.so.conf", root);
|
snprintf(line, PATH_MAX, "%setc/ld.so.conf", root);
|
||||||
if(access(line, F_OK) == 0) {
|
if(access(line, F_OK) == 0) {
|
||||||
snprintf(line, PATH_MAX, "%ssbin/ldconfig", root);
|
snprintf(line, PATH_MAX, "%ssbin/ldconfig", root);
|
||||||
if(access(line, X_OK) == 0) {
|
if(access(line, X_OK) == 0) {
|
||||||
char cmd[PATH_MAX];
|
_alpm_run_chroot(root, "ldconfig");
|
||||||
snprintf(cmd, PATH_MAX, "%s -r %s", line, root);
|
|
||||||
system(cmd);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ int _alpm_lckrm();
|
|||||||
int _alpm_unpack(const char *archive, const char *prefix, const char *fn);
|
int _alpm_unpack(const char *archive, const char *prefix, const char *fn);
|
||||||
int _alpm_rmrf(const char *path);
|
int _alpm_rmrf(const char *path);
|
||||||
int _alpm_logaction(unsigned short usesyslog, FILE *f, const char *fmt, va_list args);
|
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_ldconfig(const char *root);
|
||||||
int _alpm_str_cmp(const void *s1, const void *s2);
|
int _alpm_str_cmp(const void *s1, const void *s2);
|
||||||
char *_alpm_filecache_find(const char *filename);
|
char *_alpm_filecache_find(const char *filename);
|
||||||
|
Loading…
Reference in New Issue
Block a user