提交 730fc962 编写于 作者: E Eric Blake

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: NEric Blake <eblake@redhat.com>
上级 4594a33b
...@@ -21,13 +21,14 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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: ...@@ -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 ...@@ -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. ...@@ -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. ...@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册