summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorRaphaël Hertzog <hertzog@debian.org>2011-09-12 10:57:38 +0200
committerRaphaël Hertzog <hertzog@debian.org>2011-09-12 10:57:38 +0200
commit3609b52cca240eea58735907d9810486f560e5fe (patch)
tree603eac94219c527b41fe88affc43b3c5ffe1b772 /utils
parentbf9cefeb7abd4bb0445b3a39a74d5594e247cd8e (diff)
downloaddpkg-3609b52cca240eea58735907d9810486f560e5fe.tar.gz
update-alternatives: properly handle stat()/lstat() failures
Fix update-alternatives to always fail when lstat() or stat() fails with something else than ENOENT. There were many places testing the existence of files with “stat() == 0” and “stat() == -1 && errno == ENOENT” wrongly assuming that the only failure cause is ENOENT.
Diffstat (limited to 'utils')
-rw-r--r--utils/update-alternatives.c34
1 files changed, 25 insertions, 9 deletions
diff --git a/utils/update-alternatives.c b/utils/update-alternatives.c
index 2ac02e4d9..205672eff 100644
--- a/utils/update-alternatives.c
+++ b/utils/update-alternatives.c
@@ -1807,7 +1807,6 @@ alternative_is_broken(struct alternative *a)
char *altlnk, *wanted, *current;
struct fileset *fs;
struct slave_link *sl;
- struct stat st;
if (!alternative_has_current_link(a))
return true;
@@ -1864,10 +1863,10 @@ alternative_is_broken(struct alternative *a)
char *sl_altlnk;
/* Slave link must not exist. */
- if (lstat(sl->link, &st) == 0)
+ if (alternative_path_classify(sl->link) != ALT_PATH_MISSING)
return true;
xasprintf(&sl_altlnk, "%s/%s", altdir, sl->name);
- if (lstat(sl_altlnk, &st) == 0) {
+ if (alternative_path_classify(sl_altlnk) != ALT_PATH_MISSING) {
free(sl_altlnk);
return true;
}
@@ -2126,7 +2125,17 @@ alternative_evolve(struct alternative *a, struct alternative *b,
}
if (strcmp(old, new) != 0 &&
alternative_path_classify(old) == ALT_PATH_SYMLINK) {
- if (new_file && stat(new_file, &st) == 0) {
+ bool rename_link = false;
+
+ if (new_file) {
+ errno = 0;
+ if (stat(new_file, &st) == -1 && errno != ENOENT)
+ syserr(_("cannot stat file '%s'"),
+ new_file);
+ rename_link = (errno == 0);
+ }
+
+ if (rename_link) {
info(_("renaming %s slave link from %s to %s."),
sl->name, old, new);
checked_mv(old, new);
@@ -2193,9 +2202,13 @@ alternative_check_install_args(struct alternative *inst_alt,
alternative_check_args(inst_alt->master_name, inst_alt->master_link,
fileset->master_file);
- if (stat(fileset->master_file, &st) == -1 && errno == ENOENT)
- error(_("alternative path %s doesn't exist."),
- fileset->master_file);
+ if (stat(fileset->master_file, &st) == -1) {
+ if (errno == ENOENT)
+ error(_("alternative path %s doesn't exist."),
+ fileset->master_file);
+ else
+ syserr(_("cannot stat file '%s'"), fileset->master_file);
+ }
for (sl = inst_alt->slaves; sl; sl = sl->next) {
const char *file = fileset_get_slave(fileset, sl->name);
@@ -2469,8 +2482,11 @@ main(int argc, char **argv)
if (!alternative_has_choice(a, current_choice)) {
struct stat st;
- if (stat(current_choice, &st) == -1 &&
- errno == ENOENT) {
+ errno = 0;
+ if (stat(current_choice, &st) == -1 && errno != ENOENT)
+ syserr(_("cannot stat file '%s'"), current_choice);
+
+ if (errno == ENOENT) {
warning(_("%s/%s is dangling, it will be updated "
"with best choice."), altdir, a->master_name);
alternative_set_status(a, ALT_ST_AUTO);