* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#define _GNU_SOURCE
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <linux/unistd.h>
#include <pwd.h>
+#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "macro.h"
#include "mainloop.h"
#include "namespace.h"
+#include "raw_syscalls.h"
+#include "syscall_wrappers.h"
#include "terminal.h"
#include "utils.h"
static void lxc_put_attach_clone_payload(struct attach_clone_payload *p)
{
if (p->ipc_socket >= 0) {
- shutdown(p->ipc_socket, SHUT_RDWR);
close(p->ipc_socket);
p->ipc_socket = -EBADF;
}
if (ns_root_uid == LXC_INVALID_UID)
goto on_error;
- ret = lxc_switch_uid_gid(ns_root_uid, ns_root_gid);
- if (ret < 0)
+ if (!lxc_switch_uid_gid(ns_root_uid, ns_root_gid))
goto on_error;
}
TRACE("Loaded seccomp profile");
}
- shutdown(payload->ipc_socket, SHUT_RDWR);
close(payload->ipc_socket);
payload->ipc_socket = -EBADF;
lxc_proc_put_context_info(init_ctx);
if (new_gid == ns_root_gid)
new_gid = LXC_INVALID_GID;
- ret = lxc_switch_uid_gid(new_uid, new_gid);
- if (ret < 0)
+ if (!lxc_switch_uid_gid(new_uid, new_gid))
goto on_error;
/* We're done, so we can now do whatever the user intended us to do. */
* just fork()s away without exec'ing directly after, the socket fd will
* exist in the forked process from the other thread and any close() in
* our own child process will not really cause the socket to close
- * properly, potentiall causing the parent to hang.
+ * properly, potentially causing the parent to hang.
*
* For this reason, while IPC is still active, we have to use shutdown()
* if the child exits prematurely in order to signal that the socket is
}
if (pid == 0) {
+ if (options->attach_flags & LXC_ATTACH_TERMINAL) {
+ ret = pthread_sigmask(SIG_SETMASK,
+ &terminal.tty_state->oldmask, NULL);
+ if (ret < 0) {
+ SYSERROR("Failed to reset signal mask");
+ _exit(EXIT_FAILURE);
+ }
+ }
+
ret = attach_child_main(&payload);
if (ret < 0)
ERROR("Failed to exec");
_exit(0);
}
-int lxc_attach_run_command(void* payload)
+int lxc_attach_run_command(void *payload)
{
- lxc_attach_command_t* cmd = (lxc_attach_command_t*)payload;
+ int ret = -1;
+ lxc_attach_command_t *cmd = payload;
- execvp(cmd->program, cmd->argv);
+ ret = execvp(cmd->program, cmd->argv);
+ if (ret < 0) {
+ switch (errno) {
+ case ENOEXEC:
+ ret = 126;
+ break;
+ case ENOENT:
+ ret = 127;
+ break;
+ }
+ }
SYSERROR("Failed to exec \"%s\"", cmd->program);
- return -1;
+ return ret;
}
int lxc_attach_run_shell(void* payload)