mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
virt-login-shell: saner exit value
virt-login-shell was exiting with status 0, regardless of what the wrapped shell returned. This is unkind to users; we should behave more like env(1), nice(1), su(1), and other wrapper programs, by preserving the invoked application's status (which includes the distinction between death due to signal vs. normal death). * tools/virt-login-shell.c (main): Pass through child exit status. * tools/virt-login-shell.pod: Document exit status. Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
4594a33b4b
commit
730fc9622b
@ -21,13 +21,14 @@
|
|||||||
*/
|
*/
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
#include <getopt.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
@ -168,8 +169,8 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
virConfPtr conf = NULL;
|
virConfPtr conf = NULL;
|
||||||
const char *login_shell_path = conf_file;
|
const char *login_shell_path = conf_file;
|
||||||
pid_t cpid;
|
pid_t cpid = -1;
|
||||||
int ret = EXIT_FAILURE;
|
int ret = EXIT_CANCELED;
|
||||||
int status;
|
int status;
|
||||||
uid_t uid = getuid();
|
uid_t uid = getuid();
|
||||||
gid_t gid = getgid();
|
gid_t gid = getgid();
|
||||||
@ -195,8 +196,8 @@ main(int argc, char **argv)
|
|||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
if (virInitialize() < 0) {
|
if (virInitialize() < 0) {
|
||||||
fprintf(stderr, _("Failed to initialize libvirt Error Handling"));
|
fprintf(stderr, _("Failed to initialize libvirt error handling"));
|
||||||
return EXIT_FAILURE;
|
return EXIT_CANCELED;
|
||||||
}
|
}
|
||||||
|
|
||||||
setenv("PATH", "/bin:/usr/bin", 1);
|
setenv("PATH", "/bin:/usr/bin", 1);
|
||||||
@ -231,7 +232,7 @@ main(int argc, char **argv)
|
|||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_CANCELED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,15 +331,13 @@ main(int argc, char **argv)
|
|||||||
if (execv(shargv[0], (char *const*) shargv) < 0) {
|
if (execv(shargv[0], (char *const*) shargv) < 0) {
|
||||||
virReportSystemError(errno, _("Unable to exec shell %s"),
|
virReportSystemError(errno, _("Unable to exec shell %s"),
|
||||||
shargv[0]);
|
shargv[0]);
|
||||||
return EXIT_FAILURE;
|
virDispatchError(NULL);
|
||||||
|
return errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
|
||||||
}
|
}
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virProcessWait(cpid, &status, true) < 0)
|
/* At this point, the parent is now waiting for the child to exit,
|
||||||
goto cleanup;
|
* but as that may take a long time, we release resources now. */
|
||||||
ret = EXIT_SUCCESS;
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
for (i = 0; i < nfdlist; i++)
|
for (i = 0; i < nfdlist; i++)
|
||||||
VIR_FORCE_CLOSE(fdlist[i]);
|
VIR_FORCE_CLOSE(fdlist[i]);
|
||||||
@ -354,7 +353,11 @@ cleanup:
|
|||||||
VIR_FREE(seclabel);
|
VIR_FREE(seclabel);
|
||||||
VIR_FREE(secmodel);
|
VIR_FREE(secmodel);
|
||||||
VIR_FREE(groups);
|
VIR_FREE(groups);
|
||||||
if (ret)
|
|
||||||
|
if (virProcessWait(cpid, &status, true) == 0)
|
||||||
|
virProcessExitWithStatus(status);
|
||||||
|
|
||||||
|
if (virGetLastError())
|
||||||
virDispatchError(NULL);
|
virDispatchError(NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ virt-login-shell - tool to execute a shell within a container matching the users
|
|||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
B<virt-login-shell>
|
B<virt-login-shell> [I<OPTION>]
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
@ -47,6 +47,27 @@ variable in /etc/libvirt/virt-login-shell.conf.
|
|||||||
|
|
||||||
eg. allowed_users = [ "tom", "dick", "harry" ]
|
eg. allowed_users = [ "tom", "dick", "harry" ]
|
||||||
|
|
||||||
|
=head1 EXIT STATUS
|
||||||
|
|
||||||
|
B<virt-login-shell> normally returns the exit status of the command it
|
||||||
|
executed. If the command was killed by a signal, but that signal is not
|
||||||
|
fatal to virt-login-shell, then it returns the signal number plus 128.
|
||||||
|
|
||||||
|
Exit status generated by B<virt-login-shell> itself:
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item B<0> An option was used to learn more about this binary.
|
||||||
|
|
||||||
|
=item B<125> Generic error before attempting execution of the configured
|
||||||
|
shell; for example, if libvirtd is not running.
|
||||||
|
|
||||||
|
=item B<126> The configured shell exists but could not be executed.
|
||||||
|
|
||||||
|
=item B<127> The configured shell could not be found.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
=head1 BUGS
|
=head1 BUGS
|
||||||
|
|
||||||
Report any bugs discovered to the libvirt community via the mailing
|
Report any bugs discovered to the libvirt community via the mailing
|
||||||
@ -61,7 +82,7 @@ Alternatively report bugs to your software distributor / vendor.
|
|||||||
|
|
||||||
=head1 COPYRIGHT
|
=head1 COPYRIGHT
|
||||||
|
|
||||||
Copyright (C) 2013 Red Hat, Inc., and the authors listed in the
|
Copyright (C) 2013-2014 Red Hat, Inc., and the authors listed in the
|
||||||
libvirt AUTHORS file.
|
libvirt AUTHORS file.
|
||||||
|
|
||||||
=head1 LICENSE
|
=head1 LICENSE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user