summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2013-07-24 19:42:00 +0400
committerIgor Pashev <pashev.igor@gmail.com>2013-07-24 19:42:00 +0400
commitd074ec6481d79d6954d4d2a2e5c23976561aa6bf (patch)
tree6fc46fb4a63edda0cf78ac683f8832891f549ffc /utils
parent69ef23cecae6d9fe7c8f4677926b78ec2cd3bc17 (diff)
parentdd13db2d657c1df1f872309b8b5bcb94018bdada (diff)
downloaddpkg-d074ec6481d79d6954d4d2a2e5c23976561aa6bf.tar.gz
Merge git://git.debian.org/git/dpkg/dpkg
Conflicts: debian/changelog dpkg-deb/main.c scripts/Dpkg/Shlibs/SymbolFile.pm
Diffstat (limited to 'utils')
-rw-r--r--utils/.gitignore1
-rw-r--r--utils/Makefile.am16
-rw-r--r--utils/install-info.c66
-rw-r--r--utils/start-stop-daemon.c375
-rw-r--r--utils/t/100_update_alternatives.t340
-rw-r--r--utils/update-alternatives.c135
6 files changed, 443 insertions, 490 deletions
diff --git a/utils/.gitignore b/utils/.gitignore
index 4ba178b0c..9970040b7 100644
--- a/utils/.gitignore
+++ b/utils/.gitignore
@@ -1,4 +1,3 @@
start-stop-daemon
update-alternatives
-dpkg-install-info
t.tmp
diff --git a/utils/Makefile.am b/utils/Makefile.am
index 8a743d985..068c04c5d 100644
--- a/utils/Makefile.am
+++ b/utils/Makefile.am
@@ -41,18 +41,6 @@ start_stop_daemon_LDADD = \
$(SSD_LIBS)
endif
-if BUILD_INSTALL_INFO
-sbin_PROGRAMS += dpkg-install-info
-
-# Automake has its own install-info rule, gah
-dpkg_install_info_SOURCES = install-info.c
-
-dpkg_install_info_LDADD = \
- ../lib/compat/libcompat.a
-endif
-
-transform = s/dpkg-install-info/install-info/; $(program_transform_name)
-
install-data-local:
if BUILD_UPDATE_ALTERNATIVES
$(MKDIR_P) $(DESTDIR)$(sysconfdir)/alternatives
@@ -62,11 +50,7 @@ endif
uninstall-local:
rm -f $(DESTDIR)$(sysconfdir)/alternatives/README
-if BUILD_INSTALL_INFO
- rm -f $(DESTDIR)$(sbindir)/install-info
-endif
-TEST_VERBOSE = 0
TEST_ENV_VARS = DPKG_DATADIR=$(top_srcdir)
test_tmpdir = t.tmp
diff --git a/utils/install-info.c b/utils/install-info.c
deleted file mode 100644
index eb1679fea..000000000
--- a/utils/install-info.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * install-info.c - transitional ginstall-info wrapper
- *
- * Copyright © 2009 Raphaël Hertzog <hertzog@debian.org>
- *
- * This is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <compat.h>
-
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define SELF "/usr/sbin/install-info"
-#define WRAPPED "/usr/bin/install-info"
-
-#define warn(...) fprintf(stderr, "install-info: warning: " __VA_ARGS__)
-#define error(...) fprintf(stderr, "install-info: error: " __VA_ARGS__)
-
-int
-main(int argc, char **argv)
-{
- if (strcmp(argv[0], SELF) == 0) {
- warn("don't call programs like install-info with an absolute path,\n");
- warn("%s provided by dpkg is deprecated and will go away soon;\n",
- SELF);
- warn("its replacement lives in /usr/bin/.\n");
- }
-
- execv(WRAPPED, argv);
- if (errno == ENOENT) {
- if (getenv("DPKG_RUNNING_VERSION") != NULL) {
- const char *pkg;
-
- pkg = getenv("DPKG_MAINTSCRIPT_PACKAGE");
-
- warn("maintainer scripts should not call install-info anymore,\n");
- warn("this is handled now by a dpkg trigger provided by the\n");
- warn("install-info package; package %s should be updated.\n",
- pkg);
- } else {
- warn("nothing done since %s doesn't exist,\n", WRAPPED);
- warn("you might want to install an info-browser package.\n");
- }
- } else {
- error("can't execute %s: %s\n", WRAPPED, strerror(errno));
- return 1;
- }
-
- return 0;
-}
diff --git a/utils/start-stop-daemon.c b/utils/start-stop-daemon.c
index 2bb731fe0..61ff962a7 100644
--- a/utils/start-stop-daemon.c
+++ b/utils/start-stop-daemon.c
@@ -43,8 +43,6 @@
# error Unknown architecture - cannot build start-stop-daemon
#endif
-#define MIN_POLL_INTERVAL 20000 /* µs */
-
#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
#endif
@@ -130,10 +128,17 @@
#define PROCESS_NAME_SIZE 19
#endif
+#define MIN_POLL_INTERVAL 20000 /* µs */
+
#if defined(SYS_ioprio_set) && defined(linux)
#define HAVE_IOPRIO_SET
#endif
+#define IOPRIO_CLASS_SHIFT 13
+#define IOPRIO_PRIO_VALUE(class, prio) (((class) << IOPRIO_CLASS_SHIFT) | (prio))
+#define IO_SCHED_PRIO_MIN 0
+#define IO_SCHED_PRIO_MAX 7
+
enum {
IOPRIO_WHO_PROCESS = 1,
IOPRIO_WHO_PGRP,
@@ -179,11 +184,6 @@ static const char *progname = "";
static int nicelevel = 0;
static int umask_value = -1;
-#define IOPRIO_CLASS_SHIFT 13
-#define IOPRIO_PRIO_VALUE(class, prio) (((class) << IOPRIO_CLASS_SHIFT) | (prio))
-#define IO_SCHED_PRIO_MIN 0
-#define IO_SCHED_PRIO_MAX 7
-
static struct stat exec_stat;
#if defined(OSHurd)
static struct proc_stat_list *procset = NULL;
@@ -344,6 +344,15 @@ detach_controlling_tty(void)
close(tty_fd);
#endif
}
+
+static pid_t
+setsid(void)
+{
+ setpgid(0, 0);
+ detach_controlling_tty();
+
+ return 0;
+}
#endif
static void
@@ -361,12 +370,7 @@ daemonize(void)
_exit(0);
/* Create a new session. */
-#ifdef HAVE_SETSID
setsid();
-#else
- setpgid(0, 0);
- detach_controlling_tty();
-#endif
pid = fork();
if (pid < 0)
@@ -979,6 +983,69 @@ parse_options(int argc, char * const *argv)
badusage("--no-close is only relevant with --background");
}
+static void
+setup_options(void)
+{
+ if (execname) {
+ char *fullexecname;
+
+ /* If it's a relative path, normalize it. */
+ if (execname[0] != '/')
+ execname = newpath(changedir, execname);
+
+ if (changeroot)
+ fullexecname = newpath(changeroot, execname);
+ else
+ fullexecname = execname;
+
+ if (stat(fullexecname, &exec_stat))
+ fatal("unable to stat %s", fullexecname);
+
+ if (fullexecname != execname)
+ free(fullexecname);
+ }
+
+ if (userspec && sscanf(userspec, "%d", &user_id) != 1) {
+ struct passwd *pw;
+
+ pw = getpwnam(userspec);
+ if (!pw)
+ fatal("user '%s' not found", userspec);
+
+ user_id = pw->pw_uid;
+ }
+
+ if (changegroup && sscanf(changegroup, "%d", &runas_gid) != 1) {
+ struct group *gr;
+
+ gr = getgrnam(changegroup);
+ if (!gr)
+ fatal("group '%s' not found", changegroup);
+ changegroup = gr->gr_name;
+ runas_gid = gr->gr_gid;
+ }
+ if (changeuser) {
+ struct passwd *pw;
+ struct stat st;
+
+ if (sscanf(changeuser, "%d", &runas_uid) == 1)
+ pw = getpwuid(runas_uid);
+ else
+ pw = getpwnam(changeuser);
+ if (!pw)
+ fatal("user '%s' not found", changeuser);
+ changeuser = pw->pw_name;
+ runas_uid = pw->pw_uid;
+ if (changegroup == NULL) {
+ /* Pass the default group of this user. */
+ changegroup = ""; /* Just empty. */
+ runas_gid = pw->pw_gid;
+ }
+ if (stat(pw->pw_dir, &st) == 0)
+ setenv("HOME", pw->pw_dir, 1);
+ }
+}
+
#if defined(OSHurd)
static void
init_procset(void)
@@ -1444,6 +1511,119 @@ do_findprocs(void)
}
static void
+do_start(int argc, char **argv)
+{
+ int devnull_fd = -1;
+ gid_t rgid;
+ uid_t ruid;
+
+ do_findprocs();
+
+ if (found) {
+ if (quietmode <= 0)
+ printf("%s already running.\n", execname ? execname : "process");
+ exit(exitnodo);
+ }
+ if (testmode && quietmode <= 0) {
+ printf("Would start %s ", startas);
+ while (argc-- > 0)
+ printf("%s ", *argv++);
+ if (changeuser != NULL) {
+ printf(" (as user %s[%d]", changeuser, runas_uid);
+ if (changegroup != NULL)
+ printf(", and group %s[%d])", changegroup, runas_gid);
+ else
+ printf(")");
+ }
+ if (changeroot != NULL)
+ printf(" in directory %s", changeroot);
+ if (nicelevel)
+ printf(", and add %i to the priority", nicelevel);
+ if (proc_sched)
+ printf(", with scheduling policy %s with priority %i",
+ proc_sched->policy_name, proc_sched->priority);
+ if (io_sched)
+ printf(", with IO scheduling class %s with priority %i",
+ io_sched->policy_name, io_sched->priority);
+ printf(".\n");
+ }
+ if (testmode)
+ exit(0);
+ if (quietmode < 0)
+ printf("Starting %s...\n", startas);
+ *--argv = startas;
+ if (background)
+ /* Ok, we need to detach this process. */
+ daemonize();
+ if (background && close_io) {
+ devnull_fd = open("/dev/null", O_RDWR);
+ if (devnull_fd < 0)
+ fatal("unable to open '%s'", "/dev/null");
+ }
+ if (nicelevel) {
+ errno = 0;
+ if ((nice(nicelevel) == -1) && (errno != 0))
+ fatal("unable to alter nice level by %i", nicelevel);
+ }
+ if (proc_sched)
+ set_proc_schedule(proc_sched);
+ if (io_sched)
+ set_io_schedule(io_sched);
+ if (umask_value >= 0)
+ umask(umask_value);
+ if (mpidfile && pidfile != NULL)
+ /* User wants _us_ to make the pidfile. */
+ write_pidfile(pidfile, getpid());
+ if (changeroot != NULL) {
+ if (chdir(changeroot) < 0)
+ fatal("unable to chdir() to %s", changeroot);
+ if (chroot(changeroot) < 0)
+ fatal("unable to chroot() to %s", changeroot);
+ }
+ if (chdir(changedir) < 0)
+ fatal("unable to chdir() to %s", changedir);
+
+ rgid = getgid();
+ ruid = getuid();
+ if (changegroup != NULL) {
+ if (rgid != (gid_t)runas_gid)
+ if (setgid(runas_gid))
+ fatal("unable to set gid to %d", runas_gid);
+ }
+ if (changeuser != NULL) {
+ /* We assume that if our real user and group are the same as
+ * the ones we should switch to, the supplementary groups
+ * will be already in place. */
+ if (rgid != (gid_t)runas_gid || ruid != (uid_t)runas_uid)
+ if (initgroups(changeuser, runas_gid))
+ fatal("unable to set initgroups() with gid %d",
+ runas_gid);
+
+ if (ruid != (uid_t)runas_uid)
+ if (setuid(runas_uid))
+ fatal("unable to set uid to %s", changeuser);
+ }
+
+ /* Set a default umask for dumb programs. */
+ if (background && umask_value < 0)
+ umask(022);
+
+ if (background && close_io) {
+ int i;
+
+ dup2(devnull_fd, 0); /* stdin */
+ dup2(devnull_fd, 1); /* stdout */
+ dup2(devnull_fd, 2); /* stderr */
+
+ /* Now close all extra fds. */
+ for (i = get_open_fd_max() - 1; i >= 3; --i)
+ close(i);
+ }
+ execv(startas, argv);
+ fatal("unable to start %s", startas);
+}
+
+static void
do_stop(int sig_num, int *n_killed, int *n_notkilled)
{
struct pid_list *p;
@@ -1653,183 +1833,28 @@ run_stop_schedule(void)
int
main(int argc, char **argv)
{
- enum status_code prog_status;
- int devnull_fd = -1;
- gid_t rgid;
- uid_t ruid;
progname = argv[0];
parse_options(argc, argv);
+ setup_options();
+
argc -= optind;
argv += optind;
- if (execname) {
- char *fullexecname;
-
- /* If it's a relative path, normalize it. */
- if (execname[0] != '/')
- execname = newpath(changedir, execname);
-
- if (changeroot)
- fullexecname = newpath(changeroot, execname);
- else
- fullexecname = execname;
-
- if (stat(fullexecname, &exec_stat))
- fatal("unable to stat %s", fullexecname);
-
- if (fullexecname != execname)
- free(fullexecname);
- }
-
- if (userspec && sscanf(userspec, "%d", &user_id) != 1) {
- struct passwd *pw;
-
- pw = getpwnam(userspec);
- if (!pw)
- fatal("user '%s' not found", userspec);
-
- user_id = pw->pw_uid;
- }
-
- if (changegroup && sscanf(changegroup, "%d", &runas_gid) != 1) {
- struct group *gr = getgrnam(changegroup);
- if (!gr)
- fatal("group '%s' not found", changegroup);
- changegroup = gr->gr_name;
- runas_gid = gr->gr_gid;
- }
- if (changeuser) {
- struct passwd *pw;
- struct stat st;
-
- if (sscanf(changeuser, "%d", &runas_uid) == 1)
- pw = getpwuid(runas_uid);
- else
- pw = getpwnam(changeuser);
- if (!pw)
- fatal("user '%s' not found", changeuser);
- changeuser = pw->pw_name;
- runas_uid = pw->pw_uid;
- if (changegroup == NULL) {
- /* Pass the default group of this user. */
- changegroup = ""; /* Just empty. */
- runas_gid = pw->pw_gid;
- }
- if (stat(pw->pw_dir, &st) == 0)
- setenv("HOME", pw->pw_dir, 1);
- }
+ if (action == action_start)
+ do_start(argc, argv);
if (action == action_stop) {
int i = run_stop_schedule();
exit(i);
}
- prog_status = do_findprocs();
+ if (action == action_status) {
+ enum status_code prog_status;
- if (action == action_status)
+ prog_status = do_findprocs();
exit(prog_status);
-
- if (found) {
- if (quietmode <= 0)
- printf("%s already running.\n", execname ? execname : "process");
- exit(exitnodo);
}
- if (testmode && quietmode <= 0) {
- printf("Would start %s ", startas);
- while (argc-- > 0)
- printf("%s ", *argv++);
- if (changeuser != NULL) {
- printf(" (as user %s[%d]", changeuser, runas_uid);
- if (changegroup != NULL)
- printf(", and group %s[%d])", changegroup, runas_gid);
- else
- printf(")");
- }
- if (changeroot != NULL)
- printf(" in directory %s", changeroot);
- if (nicelevel)
- printf(", and add %i to the priority", nicelevel);
- if (proc_sched)
- printf(", with scheduling policy %s with priority %i",
- proc_sched->policy_name, proc_sched->priority);
- if (io_sched)
- printf(", with IO scheduling class %s with priority %i",
- io_sched->policy_name, io_sched->priority);
- printf(".\n");
- }
- if (testmode)
- exit(0);
- if (quietmode < 0)
- printf("Starting %s...\n", startas);
- *--argv = startas;
- if (background)
- /* Ok, we need to detach this process. */
- daemonize();
- if (background && close_io) {
- devnull_fd = open("/dev/null", O_RDWR);
- if (devnull_fd < 0)
- fatal("unable to open '%s'", "/dev/null");
- }
- if (nicelevel) {
- errno = 0;
- if ((nice(nicelevel) == -1) && (errno != 0))
- fatal("unable to alter nice level by %i", nicelevel);
- }
- if (proc_sched)
- set_proc_schedule(proc_sched);
- if (io_sched)
- set_io_schedule(io_sched);
- if (umask_value >= 0)
- umask(umask_value);
- if (mpidfile && pidfile != NULL)
- /* User wants _us_ to make the pidfile. */
- write_pidfile(pidfile, getpid());
- if (changeroot != NULL) {
- if (chdir(changeroot) < 0)
- fatal("unable to chdir() to %s", changeroot);
- if (chroot(changeroot) < 0)
- fatal("unable to chroot() to %s", changeroot);
- }
- if (chdir(changedir) < 0)
- fatal("unable to chdir() to %s", changedir);
-
- rgid = getgid();
- ruid = getuid();
- if (changegroup != NULL) {
- if (rgid != (gid_t)runas_gid)
- if (setgid(runas_gid))
- fatal("unable to set gid to %d", runas_gid);
- }
- if (changeuser != NULL) {
- /* We assume that if our real user and group are the same as
- * the ones we should switch to, the supplementary groups
- * will be already in place. */
- if (rgid != (gid_t)runas_gid || ruid != (uid_t)runas_uid)
- if (initgroups(changeuser, runas_gid))
- fatal("unable to set initgroups() with gid %d",
- runas_gid);
-
- if (ruid != (uid_t)runas_uid)
- if (setuid(runas_uid))
- fatal("unable to set uid to %s", changeuser);
- }
-
- /* Set a default umask for dumb programs. */
- if (background && umask_value < 0)
- umask(022);
-
- if (background && close_io) {
- int i;
- dup2(devnull_fd, 0); /* stdin */
- dup2(devnull_fd, 1); /* stdout */
- dup2(devnull_fd, 2); /* stderr */
-
- /* Now close all extra fds. */
- for (i = get_open_fd_max() - 1; i >= 3; --i)
- close(i);
- }
- execv(startas, argv);
- fatal("unable to start %s", startas);
+ return 0;
}
diff --git a/utils/t/100_update_alternatives.t b/utils/t/100_update_alternatives.t
index 4a786777f..6df050452 100644
--- a/utils/t/100_update_alternatives.t
+++ b/utils/t/100_update_alternatives.t
@@ -1,4 +1,4 @@
-# -*- mode: cperl;-*-
+#!/usr/bin/perl
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -26,48 +26,48 @@ my $tmpdir = 't.tmp/900_update_alternatives';
my $admindir = File::Spec->rel2abs("$tmpdir/admindir"),
my $altdir = File::Spec->rel2abs("$tmpdir/alternatives");
my $bindir = File::Spec->rel2abs("$tmpdir/bin");
-my @ua = ("$ENV{builddir}/update-alternatives", "--log", "/dev/null",
- "--quiet", "--admindir", "$admindir", "--altdir", "$altdir");
+my @ua = ("$ENV{builddir}/update-alternatives", '--log', '/dev/null',
+ '--quiet', '--admindir', "$admindir", '--altdir', "$altdir");
my %paths = (
- true => find_command("true"),
- false => find_command("false"),
- yes => find_command("yes"),
- cat => find_command("cat"),
- date => find_command("date"),
- sleep => find_command("sleep"),
+ true => find_command('true'),
+ false => find_command('false'),
+ yes => find_command('yes'),
+ cat => find_command('cat'),
+ date => find_command('date'),
+ sleep => find_command('sleep'),
);
if (! -x "$ENV{builddir}/update-alternatives") {
- plan skip_all => "update-alternatives not available";
+ plan skip_all => 'update-alternatives not available';
exit(0);
}
my $main_link = "$bindir/generic-test";
-my $main_name = "generic-test";
+my $main_name = 'generic-test';
my @choices = (
{
path => $paths{true},
priority => 20,
slaves => [
{
- "link" => "$bindir/slave2",
- name => "slave2",
+ link => "$bindir/slave2",
+ name => 'slave2',
path => $paths{cat},
},
{
- "link" => "$bindir/slave3",
- name => "slave3",
+ link => "$bindir/slave3",
+ name => 'slave3',
path => $paths{cat},
},
{
- "link" => "$bindir/slave1",
- name => "slave1",
+ link => "$bindir/slave1",
+ name => 'slave1',
path => $paths{yes},
},
{
- "link" => "$bindir/slave4",
- name => "slave4",
+ link => "$bindir/slave4",
+ name => 'slave4',
path => $paths{cat},
},
],
@@ -77,8 +77,8 @@ my @choices = (
priority => 10,
slaves => [
{
- "link" => "$bindir/slave1",
- name => "slave1",
+ link => "$bindir/slave1",
+ name => 'slave1',
path => $paths{date},
},
],
@@ -100,11 +100,11 @@ sub cleanup {
sub call_ua {
my ($params, %opts) = @_;
- spawn("exec" => [ @ua, @$params ], nocheck => 1,
- wait_child => 1, env => { LC_ALL => "C" }, %opts);
- my $test_id = "";
+ spawn(exec => [ @ua, @$params ], nocheck => 1,
+ wait_child => 1, env => { LC_ALL => 'C' }, %opts);
+ my $test_id = '';
$test_id = "$opts{test_id}: " if defined $opts{test_id};
- if ($opts{"expect_failure"}) {
+ if ($opts{expect_failure}) {
ok($? != 0, "${test_id}update-alternatives @$params should fail.") or
diag("Did not fail as expected: @ua @$params");
} else {
@@ -118,10 +118,10 @@ sub install_choice {
my $alt = $choices[$id];
my @params;
push @params, @{$opts{params}} if exists $opts{params};
- push @params, "--install", "$main_link", "$main_name",
+ push @params, '--install', "$main_link", "$main_name",
$alt->{path}, $alt->{priority};
foreach my $slave (@{ $alt->{slaves} }) {
- push @params, "--slave", $slave->{"link"}, $slave->{"name"}, $slave->{"path"};
+ push @params, '--slave', $slave->{link}, $slave->{name}, $slave->{path};
}
call_ua(\@params, %opts);
}
@@ -131,7 +131,7 @@ sub remove_choice {
my $alt = $choices[$id];
my @params;
push @params, @{$opts{params}} if exists $opts{params};
- push @params, "--remove", $main_name, $alt->{path};
+ push @params, '--remove', $main_name, $alt->{path};
call_ua(\@params, %opts);
}
@@ -139,7 +139,7 @@ sub remove_all_choices {
my (%opts) = @_;
my @params;
push @params, @{$opts{params}} if exists $opts{params};
- push @params, "--remove-all", $main_name;
+ push @params, '--remove-all', $main_name;
call_ua(\@params, %opts);
}
@@ -148,25 +148,25 @@ sub set_choice {
my $alt = $choices[$id];
my @params;
push @params, @{$opts{params}} if exists $opts{params};
- push @params, "--set", $main_name, $alt->{path};
+ push @params, '--set', $main_name, $alt->{path};
call_ua(\@params, %opts);
}
sub config_choice {
my ($id, %opts) = @_;
- my ($input, $output) = ("", "");
+ my ($input, $output) = ('', '');
if ($id >= 0) {
my $alt = $choices[$id];
$input = $alt->{path};
} else {
- $input = "0";
+ $input = '0';
}
$input .= "\n";
$opts{from_string} = \$input;
$opts{to_string} = \$output;
my @params;
push @params, @{$opts{params}} if exists $opts{params};
- push @params, "--config", $main_name;
+ push @params, '--config', $main_name;
call_ua(\@params, %opts);
}
@@ -175,22 +175,24 @@ sub get_slaves_status {
my %slaves;
# None of the slaves are installed
foreach my $alt (@choices) {
- for(my $i = 0; $i < @{$alt->{slaves}}; $i++) {
+ for my $i (0 .. @{$alt->{slaves}} - 1) {
$slaves{$alt->{slaves}[$i]{name}} = $alt->{slaves}[$i];
- $slaves{$alt->{slaves}[$i]{name}}{"installed"} = 0;
+ $slaves{$alt->{slaves}[$i]{name}}{installed} = 0;
}
}
# except those of the current alternative (minus optional slaves)
if (defined($id)) {
my $alt = $choices[$id];
- for(my $i = 0; $i < @{$alt->{slaves}}; $i++) {
+ for my $i (0 .. @{$alt->{slaves}} - 1) {
$slaves{$alt->{slaves}[$i]{name}} = $alt->{slaves}[$i];
if (-e $alt->{slaves}[$i]{path}) {
- $slaves{$alt->{slaves}[$i]{name}}{"installed"} = 1;
+ $slaves{$alt->{slaves}[$i]{name}}{installed} = 1;
}
}
}
- return sort { $a->{name} cmp $b->{name} } values %slaves;
+ my @slaves = sort { $a->{name} cmp $b->{name} } values %slaves;
+
+ return @slaves;
}
sub check_link {
@@ -202,7 +204,7 @@ sub check_no_link {
my ($link, $msg) = @_;
lstat($link);
ok(!-e _, "$msg: $link still exists.");
- ok(1, "fake test"); # Same number of tests as check_link
+ ok(1, 'fake test'); # Same number of tests as check_link
}
sub check_slaves {
@@ -210,10 +212,10 @@ sub check_slaves {
foreach my $slave (get_slaves_status($id)) {
if ($slave->{installed}) {
check_link("$altdir/$slave->{name}", $slave->{path}, $msg);
- check_link($slave->{"link"}, "$altdir/$slave->{name}", $msg);
+ check_link($slave->{link}, "$altdir/$slave->{name}", $msg);
} else {
check_no_link("$altdir/$slave->{name}", $msg);
- check_no_link($slave->{"link"}, $msg);
+ check_no_link($slave->{link}, $msg);
}
}
}
@@ -223,7 +225,7 @@ sub check_choice {
my $output;
if (defined $id) {
# Check status
- call_ua([ "--query", "$main_name" ], to_string => \$output, test_id => $msg);
+ call_ua([ '--query', "$main_name" ], to_string => \$output, test_id => $msg);
$output =~ /^Status: (.*)$/im;
is($1, $mode, "$msg: status is not $mode.");
# Check links
@@ -232,7 +234,7 @@ sub check_choice {
check_link($main_link, "$altdir/$main_name", $msg);
check_slaves($id, $msg);
} else {
- call_ua([ "--query", "$main_name" ], error_to_string => \$output,
+ call_ua([ '--query', "$main_name" ], error_to_string => \$output,
expect_failure => 1, test_id => $msg);
ok($output =~ /no alternatives/, "$msg: bad error message for --query.");
# Check that all links have disappeared
@@ -248,18 +250,18 @@ cleanup();
remove_choice(0);
# successive install in auto mode
install_choice(1);
-check_choice(1, "auto", "initial install 1");
+check_choice(1, 'auto', 'initial install 1');
install_choice(2); # 2 is lower prio, stays at 1
-check_choice(1, "auto", "initial install 2");
+check_choice(1, 'auto', 'initial install 2');
install_choice(0); # 0 is higher priority
-check_choice(0, "auto", "initial install 3");
+check_choice(0, 'auto', 'initial install 3');
# verify that the administrative file is sorted properly
{
local $/ = undef;
- open(FILE, "<", "$admindir/generic-test") or die $!;
- my $content = <FILE>;
- close(FILE);
+ open(my $db_fh, '<', "$admindir/generic-test") or die $!;
+ my $content = <$db_fh>;
+ close($db_fh);
my $expected =
"auto
@@ -288,101 +290,101 @@ $bindir/slave4
$expected .= $alt->{path} . "\n";
$expected .= $alt->{priority} . "\n";
foreach my $slave_name (sort keys %slaves) {
- $expected .= $slaves{$slave_name}{$alt->{path}}{path} || "";
+ $expected .= $slaves{$slave_name}{$alt->{path}}{path} || '';
$expected .= "\n";
}
}
$expected .= "\n";
- is($content, $expected, "administrative file is as expected");
+ is($content, $expected, 'administrative file is as expected');
}
# manual change with --set-selections
my $input = "doesntexist auto $paths{date}\ngeneric-test manual $paths{false}\n";
-my $output = "";
-call_ua(["--set-selections"], from_string => \$input,
- to_string => \$output, test_id => "manual update with --set-selections");
-check_choice(1, "manual", "manual update with --set-selections");
+my $output = '';
+call_ua(['--set-selections'], from_string => \$input,
+ to_string => \$output, test_id => 'manual update with --set-selections');
+check_choice(1, 'manual', 'manual update with --set-selections');
$input = "generic-test auto $paths{true}\n";
-call_ua(["--set-selections"], from_string => \$input,
- to_string => \$output, test_id => "auto update with --set-selections");
-check_choice(0, "auto", "auto update with --set-selections");
+call_ua(['--set-selections'], from_string => \$input,
+ to_string => \$output, test_id => 'auto update with --set-selections');
+check_choice(0, 'auto', 'auto update with --set-selections');
# manual change with set
-set_choice(2, test_id => "manual update with --set");
-check_choice(2, "manual", "manual update with --set"); # test #388313
-remove_choice(2, test_id => "remove manual, back to auto");
-check_choice(0, "auto", "remove manual, back to auto");
-remove_choice(0, test_id => "remove best");
-check_choice(1, "auto", "remove best");
-remove_choice(1, test_id => "no alternative left");
-check_choice(undef, "", "no alternative left");
+set_choice(2, test_id => 'manual update with --set');
+check_choice(2, 'manual', 'manual update with --set'); # test #388313
+remove_choice(2, test_id => 'remove manual, back to auto');
+check_choice(0, 'auto', 'remove manual, back to auto');
+remove_choice(0, test_id => 'remove best');
+check_choice(1, 'auto', 'remove best');
+remove_choice(1, test_id => 'no alternative left');
+check_choice(undef, '', 'no alternative left');
# single choice in manual mode, to be removed
install_choice(1);
set_choice(1);
-check_choice(1, "manual", "single manual choice");
+check_choice(1, 'manual', 'single manual choice');
remove_choice(1);
-check_choice(undef, "", "removal single manual");
+check_choice(undef, '', 'removal single manual');
# test --remove-all
install_choice(0);
install_choice(1);
install_choice(2);
-remove_all_choices(test_id => "remove all");
-check_choice(undef, "", "no alternative left");
+remove_all_choices(test_id => 'remove all');
+check_choice(undef, '', 'no alternative left');
# check auto-recovery of user mistakes (#100135)
install_choice(1);
-ok(unlink("$bindir/generic-test"), "failed removal");
-ok(unlink("$bindir/slave1"), "failed removal");
+ok(unlink("$bindir/generic-test"), 'failed removal');
+ok(unlink("$bindir/slave1"), 'failed removal');
install_choice(1);
-check_choice(1, "auto", "recreate links in auto mode");
+check_choice(1, 'auto', 'recreate links in auto mode');
set_choice(1);
-ok(unlink("$bindir/generic-test"), "failed removal");
-ok(unlink("$bindir/slave1"), "failed removal");
+ok(unlink("$bindir/generic-test"), 'failed removal');
+ok(unlink("$bindir/slave1"), 'failed removal');
install_choice(1);
-check_choice(1, "manual", "recreate links in manual mode");
+check_choice(1, 'manual', 'recreate links in manual mode');
# check recovery of /etc/alternatives/*
install_choice(0);
-ok(unlink("$altdir/generic-test"), "failed removal");
+ok(unlink("$altdir/generic-test"), 'failed removal');
install_choice(1);
-check_choice(0, "auto", "<altdir>/generic-test lost, back to auto");
+check_choice(0, 'auto', '<altdir>/generic-test lost, back to auto');
# test --config
config_choice(0);
-check_choice(0, "manual", "config to best but manual");
+check_choice(0, 'manual', 'config to best but manual');
config_choice(1);
-check_choice(1, "manual", "config to manual");
+check_choice(1, 'manual', 'config to manual');
config_choice(-1);
-check_choice(0, "auto", "config auto");
+check_choice(0, 'auto', 'config auto');
# test rename of links
install_choice(0);
-my $old_slave = $choices[0]{"slaves"}[0]{"link"};
+my $old_slave = $choices[0]{slaves}[0]{link};
my $old_link = $main_link;
-$choices[0]{"slaves"}[0]{"link"} = "$bindir/more/generic-slave";
+$choices[0]{slaves}[0]{link} = "$bindir/more/generic-slave";
$main_link = "$bindir/more/mytest";
install_choice(0);
-check_choice(0, "auto", "test rename of links");
-check_no_link($old_link, "test rename of links");
-check_no_link($old_slave, "test rename of links");
+check_choice(0, 'auto', 'test rename of links');
+check_no_link($old_link, 'test rename of links');
+check_no_link($old_slave, 'test rename of links');
# rename with installing other alternatives
$old_link = $main_link;
$main_link = "$bindir/generic-test";
install_choice(1);
-check_choice(0, "auto", "rename link");
-check_no_link($old_link, "rename link");
+check_choice(0, 'auto', 'rename link');
+check_no_link($old_link, 'rename link');
# rename with lost file
unlink($old_slave);
-$old_slave = $choices[0]{"slaves"}[0]{"link"};
-$choices[0]{"slaves"}[0]{"link"} = "$bindir/generic-slave-bis";
+$old_slave = $choices[0]{slaves}[0]{link};
+$choices[0]{slaves}[0]{link} = "$bindir/generic-slave-bis";
install_choice(0);
-check_choice(0, "auto", "rename lost file");
-check_no_link($old_slave, "rename lost file");
+check_choice(0, 'auto', 'rename lost file');
+check_no_link($old_slave, 'rename lost file');
# update of alternative with many slaves not currently installed
# and the link of the renamed slave exists while it should not
set_choice(1);
symlink("$paths{cat}", "$bindir/generic-slave-bis");
-$choices[0]{"slaves"}[0]{"link"} = "$bindir/slave2";
-install_choice(0, test_id => "update with non-installed slaves");
+$choices[0]{slaves}[0]{link} = "$bindir/slave2";
+install_choice(0, test_id => 'update with non-installed slaves');
check_no_link("$bindir/generic-slave-bis",
- "drop renamed symlink that should not be installed");
+ 'drop renamed symlink that should not be installed');
# test install with empty admin file (#457863)
cleanup();
@@ -391,110 +393,110 @@ install_choice(0);
# test install with garbage admin file
cleanup();
system("echo garbage > $admindir/generic-test");
-install_choice(0, error_to_file => "/dev/null", expect_failure => 1);
+install_choice(0, error_to_file => '/dev/null', expect_failure => 1);
# test invalid usages
cleanup();
install_choice(0);
# try to install a slave alternative as new master
-call_ua(["--install", "$bindir/testmaster", "slave1", "$paths{date}", "10"],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/testmaster", 'slave1', "$paths{date}", '10'],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# try to install a master alternative as slave
-call_ua(["--install", "$bindir/testmaster", "testmaster", "$paths{date}", "10",
- "--slave", "$bindir/testslave", "generic-test", "$paths{true}" ],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
+ '--slave', "$bindir/testslave", 'generic-test', "$paths{true}" ],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# try to reuse master link in slave
-call_ua(["--install", "$bindir/testmaster", "testmaster", "$paths{date}", "10",
- "--slave", "$bindir/testmaster", "testslave", "$paths{true}" ],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
+ '--slave', "$bindir/testmaster", 'testslave', "$paths{true}" ],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# try to reuse links in master alternative
-call_ua(["--install", "$bindir/slave1", "testmaster", "$paths{date}", "10"],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/slave1", 'testmaster', "$paths{date}", '10'],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# try to reuse links in slave alternative
-call_ua(["--install", "$bindir/testmaster", "testmaster", "$paths{date}", "10",
- "--slave", "$bindir/generic-test", "testslave", "$paths{true}" ],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
+ '--slave', "$bindir/generic-test", 'testslave', "$paths{true}" ],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# try to reuse slave link in another slave alternative of another choice of
# the same main alternative
-call_ua(["--install", $main_link, $main_name, "$paths{date}", "10",
- "--slave", "$bindir/slave1", "testslave", "$paths{true}" ],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', $main_link, $main_name, "$paths{date}", '10',
+ '--slave', "$bindir/slave1", 'testslave', "$paths{true}" ],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# lack of absolute filenames in links or file path, non-existing path,
-call_ua(["--install", "../testmaster", "testmaster", "$paths{date}", "10"],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
-call_ua(["--install", "$bindir/testmaster", "testmaster", "./update-alternatives.pl", "10"],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', '../testmaster', 'testmaster', "$paths{date}", '10'],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
+call_ua(['--install', "$bindir/testmaster", 'testmaster', './update-alternatives.pl', '10'],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# non-existing alternative path
-call_ua(["--install", "$bindir/testmaster", "testmaster", "$bindir/doesntexist", "10"],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/testmaster", 'testmaster', "$bindir/doesntexist", '10'],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# invalid alternative name in master
-call_ua(["--install", "$bindir/testmaster", "test/master", "$paths{date}", "10"],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/testmaster", 'test/master', "$paths{date}", '10'],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# invalid alternative name in slave
-call_ua(["--install", "$bindir/testmaster", "testmaster", "$paths{date}", "10",
- "--slave", "$bindir/testslave", "test slave", "$paths{true}" ],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
+ '--slave', "$bindir/testslave", 'test slave', "$paths{true}" ],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# install in non-existing dir should fail
-call_ua(["--install", "$bindir/doesntexist/testmaster", "testmaster", "$paths{date}", "10",
- "--slave", "$bindir/testslave", "testslave", "$paths{true}" ],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
-call_ua(["--install", "$bindir/testmaster", "testmaster", "$paths{date}", "10",
- "--slave", "$bindir/doesntexist/testslave", "testslave", "$paths{true}" ],
- expect_failure => 1, to_file => "/dev/null", error_to_file => "/dev/null");
+call_ua(['--install', "$bindir/doesntexist/testmaster", 'testmaster', "$paths{date}", '10',
+ '--slave', "$bindir/testslave", 'testslave', "$paths{true}" ],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
+call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
+ '--slave', "$bindir/doesntexist/testslave", 'testslave', "$paths{true}" ],
+ expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
# non-existing alternative path in slave is not a failure
-my $old_path = $choices[0]{"slaves"}[0]{"path"};
-$old_slave = $choices[0]{"slaves"}[0]{"link"};
-$choices[0]{"slaves"}[0]{"path"} = "$bindir/doesntexist";
-$choices[0]{"slaves"}[0]{"link"} = "$bindir/baddir/slave2";
+my $old_path = $choices[0]{slaves}[0]{path};
+$old_slave = $choices[0]{slaves}[0]{link};
+$choices[0]{slaves}[0]{path} = "$bindir/doesntexist";
+$choices[0]{slaves}[0]{link} = "$bindir/baddir/slave2";
# test rename of slave link that existed but that doesn't anymore
# and link is moved into non-existing dir at the same time
install_choice(0);
-check_choice(0, "auto", "optional renamed slave2 in non-existing dir");
+check_choice(0, 'auto', 'optional renamed slave2 in non-existing dir');
# same but on fresh install
cleanup();
install_choice(0);
-check_choice(0, "auto", "optional slave2 in non-existing dir");
-$choices[0]{"slaves"}[0]{"link"} = $old_slave;
+check_choice(0, 'auto', 'optional slave2 in non-existing dir');
+$choices[0]{slaves}[0]{link} = $old_slave;
# test fresh install with a non-existing slave file
cleanup();
install_choice(0);
-check_choice(0, "auto", "optional slave2");
-$choices[0]{"slaves"}[0]{"path"} = $old_path;
+check_choice(0, 'auto', 'optional slave2');
+$choices[0]{slaves}[0]{path} = $old_path;
# test management of pre-existing files
cleanup();
system("touch $main_link $bindir/slave1");
install_choice(0);
-ok(!-l $main_link, "install preserves files that should be links");
-ok(!-l "$bindir/slave1", "install preserves files that should be slave links");
+ok(!-l $main_link, 'install preserves files that should be links');
+ok(!-l "$bindir/slave1", 'install preserves files that should be slave links');
remove_choice(0);
-ok(-f $main_link, "removal keeps real file installed as master link");
-ok(-f "$bindir/slave1", "removal keeps real files installed as slave links");
-install_choice(0, params => ["--force"]);
-check_choice(0, "auto", "install --force replaces files with links");
+ok(-f $main_link, 'removal keeps real file installed as master link');
+ok(-f "$bindir/slave1", 'removal keeps real files installed as slave links');
+install_choice(0, params => ['--force']);
+check_choice(0, 'auto', 'install --force replaces files with links');
# test management of pre-existing files #2
cleanup();
system("touch $main_link $bindir/slave2");
install_choice(0);
install_choice(1);
-ok(!-l $main_link, "inactive install preserves files that should be links");
-ok(!-l "$bindir/slave2", "inactive install preserves files that should be slave links");
-ok(-f $main_link, "inactive install keeps real file installed as master link");
-ok(-f "$bindir/slave2", "inactive install keeps real files installed as slave links");
+ok(!-l $main_link, 'inactive install preserves files that should be links');
+ok(!-l "$bindir/slave2", 'inactive install preserves files that should be slave links');
+ok(-f $main_link, 'inactive install keeps real file installed as master link');
+ok(-f "$bindir/slave2", 'inactive install keeps real files installed as slave links');
set_choice(1);
-ok(!-l $main_link, "manual switching preserves files that should be links");
-ok(!-l "$bindir/slave2", "manual switching preserves files that should be slave links");
-ok(-f $main_link, "manual switching keeps real file installed as master link");
-ok(-f "$bindir/slave2", "manual switching keeps real files installed as slave links");
+ok(!-l $main_link, 'manual switching preserves files that should be links');
+ok(!-l "$bindir/slave2", 'manual switching preserves files that should be slave links');
+ok(-f $main_link, 'manual switching keeps real file installed as master link');
+ok(-f "$bindir/slave2", 'manual switching keeps real files installed as slave links');
remove_choice(1);
-ok(!-l $main_link, "auto switching preserves files that should be links");
-ok(!-l "$bindir/slave2", "auto switching preserves files that should be slave links");
-ok(-f $main_link, "auto switching keeps real file installed as master link");
-ok(-f "$bindir/slave2", "auto switching keeps real files installed as slave links");
-remove_all_choices(params => ["--force"]);
-ok(!-e "$bindir/slave2", "forced removeall drops real files installed as slave links");
+ok(!-l $main_link, 'auto switching preserves files that should be links');
+ok(!-l "$bindir/slave2", 'auto switching preserves files that should be slave links');
+ok(-f $main_link, 'auto switching keeps real file installed as master link');
+ok(-f "$bindir/slave2", 'auto switching keeps real files installed as slave links');
+remove_all_choices(params => ['--force']);
+ok(!-e "$bindir/slave2", 'forced removeall drops real files installed as slave links');
# test management of pre-existing files #3
cleanup();
@@ -502,15 +504,15 @@ system("touch $main_link $bindir/slave2");
install_choice(0);
install_choice(1);
remove_choice(0);
-ok(!-l $main_link, "removal + switching preserves files that should be links");
-ok(!-l "$bindir/slave2", "removal + switching preserves files that should be slave links");
-ok(-f $main_link, "removal + switching keeps real file installed as master link");
-ok(-f "$bindir/slave2", "removal + switching keeps real files installed as slave links");
+ok(!-l $main_link, 'removal + switching preserves files that should be links');
+ok(!-l "$bindir/slave2", 'removal + switching preserves files that should be slave links');
+ok(-f $main_link, 'removal + switching keeps real file installed as master link');
+ok(-f "$bindir/slave2", 'removal + switching keeps real files installed as slave links');
install_choice(0);
-ok(!-l $main_link, "install + switching preserves files that should be links");
-ok(!-l "$bindir/slave2", "install + switching preserves files that should be slave links");
-ok(-f $main_link, "install + switching keeps real file installed as master link");
-ok(-f "$bindir/slave2", "install + switching keeps real files installed as slave links");
-set_choice(1, params => ["--force"]);
-ok(!-e "$bindir/slave2", "forced switching w/o slave drops real files installed as slave links");
-check_choice(1, "manual", "set --force replaces files with links");
+ok(!-l $main_link, 'install + switching preserves files that should be links');
+ok(!-l "$bindir/slave2", 'install + switching preserves files that should be slave links');
+ok(-f $main_link, 'install + switching keeps real file installed as master link');
+ok(-f "$bindir/slave2", 'install + switching keeps real files installed as slave links');
+set_choice(1, params => ['--force']);
+ok(!-e "$bindir/slave2", 'forced switching w/o slave drops real files installed as slave links');
+check_choice(1, 'manual', 'set --force replaces files with links');
diff --git a/utils/update-alternatives.c b/utils/update-alternatives.c
index 5f4364b09..d88ded5b7 100644
--- a/utils/update-alternatives.c
+++ b/utils/update-alternatives.c
@@ -173,7 +173,9 @@ badusage(char const *fmt, ...)
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n\n");
- usage();
+ fprintf(stderr, _("Use '%s --help' for program usage information."),
+ PROGNAME);
+ fprintf(stderr, "\n");
exit(2);
}
@@ -401,29 +403,19 @@ log_msg(const char *fmt, ...)
static int
spawn(const char *prog, const char *args[])
{
- const char **cmd;
- int i = 0;
pid_t pid, r;
int status;
- while (args[i++]);
- cmd = xmalloc(sizeof(char *) * (i + 2));
- cmd[0] = prog;
- for (i = 0; args[i]; i++)
- cmd[i + 1] = args[i];
- cmd[i + 1] = NULL;
-
pid = fork();
if (pid == -1)
error(_("fork failed"));
if (pid == 0) {
- execvp(prog, (char *const *)cmd);
+ execvp(prog, (char *const *)args);
syserr(_("unable to execute %s (%s)"), prog, prog);
}
while ((r = waitpid(pid, &status, 0)) == -1 && errno == EINTR) ;
if (r != pid)
error(_("wait for subprocess %s failed"), prog);
- free(cmd);
return status;
}
@@ -443,8 +435,9 @@ subcall(const char *prog, ...)
va_end(args);
/* Prepare table for all parameters */
- cmd = xmalloc(sizeof(*cmd) * (nb_opts + count + 1));
+ cmd = xmalloc(sizeof(*cmd) * (nb_opts + count + 2));
i = 0;
+ cmd[i++] = prog;
for (j = 0; j < nb_opts; j++)
cmd[i++] = pass_opts[j];
va_start(args, prog);
@@ -472,7 +465,7 @@ rename_mv(const char *src, const char *dst)
return false;
if (rename(src, dst) != 0) {
- const char *args[3] = { src, dst, NULL };
+ const char *args[] = { "mv", src, dst, NULL };
int r;
r = spawn("mv", args);
if (WIFEXITED(r) && WEXITSTATUS(r) == 0)
@@ -659,6 +652,8 @@ struct commit_operation {
struct alternative {
char *master_name;
char *master_link;
+ char *current;
+
enum alternative_status {
ALT_ST_UNKNOWN,
ALT_ST_AUTO,
@@ -672,6 +667,7 @@ struct alternative {
int ref_count;
bool modified;
+ bool known_current;
};
static void
@@ -698,11 +694,13 @@ alternative_new(const char *name)
alt = xmalloc(sizeof(*alt));
alt->master_name = xstrdup(name);
alt->master_link = NULL;
+ alt->current = NULL;
alt->status = ALT_ST_UNKNOWN;
alt->slaves = NULL;
alt->choices = NULL;
alt->commit_ops = NULL;
alt->modified = false;
+ alt->known_current = false;
alt->ref_count = 1;
return alt;
@@ -752,6 +750,8 @@ alternative_reset(struct alternative *alt)
{
struct slave_link *slave;
+ free(alt->current);
+ alt->current = NULL;
free(alt->master_link);
alt->master_link = NULL;
while (alt->slaves) {
@@ -762,6 +762,7 @@ alternative_reset(struct alternative *alt)
alternative_choices_free(alt);
alternative_commit_operations_free(alt);
alt->modified = false;
+ alt->known_current = false;
}
static void
@@ -1039,8 +1040,8 @@ struct altdb_context {
char *filename;
enum altdb_flags flags;
bool modified;
- void DPKG_ATTR_PRINTF(2) (*bad_format)(struct altdb_context *,
- const char *format, ...);
+ void DPKG_ATTR_NORET DPKG_ATTR_PRINTF(2)
+ (*bad_format)(struct altdb_context *, const char *format, ...);
jmp_buf on_error;
};
@@ -1197,12 +1198,10 @@ alternative_parse_fileset(struct alternative *a, struct altdb_context *ctx)
return false;
}
- for (fs = a->choices; fs; fs = fs->next) {
- if (strcmp(fs->master_file, master_file) == 0) {
- free(master_file);
- ctx->bad_format(ctx, _("duplicate path %s"),
- fs->master_file);
- }
+ fs = alternative_get_fileset(a, master_file);
+ if (fs) {
+ free(master_file);
+ ctx->bad_format(ctx, _("duplicate path %s"), master_file);
}
if (stat(master_file, &st)) {
@@ -1410,30 +1409,30 @@ alternative_save(struct alternative *a)
free(file);
}
-static struct fileset *
-alternative_get_best(struct alternative *a)
+static const char *
+alternative_set_current(struct alternative *a, char *new_choice)
{
- struct fileset *fs, *best;
-
- for (best = fs = a->choices; fs; fs = fs->next)
- if (fs->priority > best->priority)
- best = fs;
+ a->known_current = true;
+ a->current = new_choice;
- return best;
+ return new_choice;
}
-static char *
+static const char *
alternative_get_current(struct alternative *a)
{
struct stat st;
char *curlink;
char *file;
+ if (a->known_current)
+ return a->current;
+
xasprintf(&curlink, "%s/%s", altdir, a->master_name);
if (lstat(curlink, &st)) {
if (errno == ENOENT) {
free(curlink);
- return NULL;
+ return alternative_set_current(a, NULL);
}
syserr(_("cannot stat file '%s'"), curlink);
}
@@ -1441,7 +1440,29 @@ alternative_get_current(struct alternative *a)
file = xreadlink(curlink);
free(curlink);
- return file;
+ return alternative_set_current(a, file);
+}
+
+static struct fileset *
+alternative_get_best(struct alternative *a)
+{
+ struct fileset *fs, *best;
+ const char *current;
+
+ current = alternative_get_current(a);
+ if (current)
+ best = alternative_get_fileset(a, current);
+ else
+ best = NULL;
+
+ if (best == NULL)
+ best = a->choices;
+
+ for (fs = a->choices; fs; fs = fs->next)
+ if (fs->priority > best->priority)
+ best = fs;
+
+ return best;
}
static void
@@ -1449,7 +1470,7 @@ alternative_display_query(struct alternative *a)
{
struct fileset *best, *fs;
struct slave_link *sl;
- char *current;
+ const char *current;
pr("Name: %s", a->master_name);
pr("Link: %s", a->master_link);
@@ -1464,7 +1485,6 @@ alternative_display_query(struct alternative *a)
pr("Best: %s", best->master_file);
current = alternative_get_current(a);
pr("Value: %s", current ? current : "none");
- free(current);
for (fs = a->choices; fs; fs = fs->next) {
printf("\n");
@@ -1484,7 +1504,7 @@ alternative_display_query(struct alternative *a)
static void
alternative_display_user(struct alternative *a)
{
- char *current;
+ const char *current;
struct fileset *fs;
struct slave_link *sl;
@@ -1493,7 +1513,6 @@ alternative_display_user(struct alternative *a)
current = alternative_get_current(a);
if (current) {
pr(_(" link currently points to %s"), current);
- free(current);
} else {
pr(_(" link currently absent"));
}
@@ -1526,7 +1545,8 @@ alternative_display_list(struct alternative *a)
static const char *
alternative_select_choice(struct alternative *a)
{
- char *current, *ret, selection[_POSIX_PATH_MAX];
+ const char *current;
+ char *ret, selection[_POSIX_PATH_MAX];
struct fileset *best, *fs;
int len, idx;
@@ -1573,7 +1593,6 @@ alternative_select_choice(struct alternative *a)
"or type selection number: "));
ret = fgets(selection, sizeof(selection), stdin);
if (ret == NULL || strlen(selection) == 0) {
- free(current);
return NULL;
}
selection[strlen(selection) - 1] = '\0';
@@ -1587,7 +1606,6 @@ alternative_select_choice(struct alternative *a)
/* Look up by index */
if (idx == 0) {
alternative_set_status(a, ALT_ST_AUTO);
- free(current);
return xstrdup(best->master_file);
}
idx--;
@@ -1595,17 +1613,14 @@ alternative_select_choice(struct alternative *a)
fs = fs->next;
if (fs) {
alternative_set_status(a, ALT_ST_MANUAL);
- free(current);
return xstrdup(fs->master_file);
}
} else {
/* Look up by name */
- for (fs = a->choices; fs; fs = fs->next) {
- if (strcmp(fs->master_file, selection) == 0) {
- alternative_set_status(a, ALT_ST_MANUAL);
- free(current);
- return xstrdup(selection);
- }
+ fs = alternative_get_fileset(a, selection);
+ if (fs) {
+ alternative_set_status(a, ALT_ST_MANUAL);
+ return xstrdup(selection);
}
}
}
@@ -1826,7 +1841,8 @@ alternative_remove(struct alternative *a)
static bool
alternative_is_broken(struct alternative *a)
{
- char *altlnk, *wanted, *current;
+ const char *current;
+ char *altlnk, *wanted;
struct fileset *fs;
struct slave_link *sl;
@@ -1848,12 +1864,10 @@ alternative_is_broken(struct alternative *a)
if (current == NULL)
return true;
- if (!alternative_has_choice(a, current)) {
- free(current);
+ if (!alternative_has_choice(a, current))
return false;
- }
+
fs = alternative_get_fileset(a, current);
- free(current);
/* Check slaves */
for (sl = a->slaves; sl; sl = sl->next) {
@@ -2042,13 +2056,12 @@ alternative_get_selections(void)
alternative_map_load_names(alt_map_obj);
for (am = alt_map_obj; am && am->item; am = am->next) {
- char *current;
+ const char *current;
current = alternative_get_current(am->item);
printf("%-30s %-8s %s\n", am->key,
alternative_status_string(am->item->status),
current ? current : "");
- free(current);
}
alternative_map_free(alt_map_obj);
@@ -2252,7 +2265,7 @@ alternative_evolve(struct alternative *a, struct alternative *b,
static void
alternative_update(struct alternative *a,
- char *current_choice, const char *new_choice)
+ const char *current_choice, const char *new_choice)
{
/* No choice left, remove everything. */
if (!alternative_choices_count(a)) {
@@ -2436,7 +2449,8 @@ main(int argc, char **argv)
/* Set of files to install in the alternative. */
struct fileset *fileset = NULL;
/* Path of alternative we are offering. */
- char *path = NULL, *current_choice = NULL;
+ char *path = NULL;
+ const char *current_choice = NULL;
const char *new_choice = NULL;
int i = 0;
@@ -2483,13 +2497,8 @@ main(int argc, char **argv)
prio = strtol(prio_str, &prio_end, 10);
if (prio_str == prio_end || *prio_end != '\0')
badusage(_("priority must be an integer"));
- if (prio < INT_MIN || prio > INT_MAX || errno == ERANGE) {
- /* XXX: Switch back to error on 1.17.x. */
- prio = clamp(prio, INT_MIN, INT_MAX);
- warning(_("priority is out of range: "
- "%s clamped to %ld"),
- prio_str, prio);
- }
+ if (prio < INT_MIN || prio > INT_MAX || errno == ERANGE)
+ badusage(_("priority is out of range"));
a = alternative_new(argv[i + 2]);
inst_alt = alternative_new(argv[i + 2]);