*/
#include <config.h>
-#include <stdarg.h>
-#include <getopt.h>
-#include <stdio.h>
#include <errno.h>
-#include <stdlib.h>
#include <fnmatch.h>
+#include <getopt.h>
#include <locale.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
#include "internal.h"
#include "virerror.h"
{
virConfPtr conf = NULL;
const char *login_shell_path = conf_file;
- pid_t cpid;
- int ret = EXIT_FAILURE;
+ pid_t cpid = -1;
+ int ret = EXIT_CANCELED;
int status;
uid_t uid = getuid();
gid_t gid = getgid();
{NULL, 0, NULL, 0}
};
if (virInitialize() < 0) {
- fprintf(stderr, _("Failed to initialize libvirt Error Handling"));
- return EXIT_FAILURE;
+ fprintf(stderr, _("Failed to initialize libvirt error handling"));
+ return EXIT_CANCELED;
}
setenv("PATH", "/bin:/usr/bin", 1);
case '?':
default:
usage();
- exit(EXIT_FAILURE);
+ exit(EXIT_CANCELED);
}
}
if (execv(shargv[0], (char *const*) shargv) < 0) {
virReportSystemError(errno, _("Unable to exec shell %s"),
shargv[0]);
- return EXIT_FAILURE;
+ virDispatchError(NULL);
+ return errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
}
- return EXIT_SUCCESS;
}
- if (virProcessWait(cpid, &status, true) < 0)
- goto cleanup;
- ret = EXIT_SUCCESS;
-
+ /* At this point, the parent is now waiting for the child to exit,
+ * but as that may take a long time, we release resources now. */
cleanup:
for (i = 0; i < nfdlist; i++)
VIR_FORCE_CLOSE(fdlist[i]);
VIR_FREE(seclabel);
VIR_FREE(secmodel);
VIR_FREE(groups);
- if (ret)
+
+ if (virProcessWait(cpid, &status, true) == 0)
+ virProcessExitWithStatus(status);
+
+ if (virGetLastError())
virDispatchError(NULL);
return ret;
}
=head1 SYNOPSIS
-B<virt-login-shell>
+B<virt-login-shell> [I<OPTION>]
=head1 DESCRIPTION
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
Report any bugs discovered to the libvirt community via the mailing
=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.
=head1 LICENSE