add interactive mode for /bin/sh entrypoint
This commit is contained in:
parent
8ab9a46d96
commit
76f7d7d1af
@ -39,12 +39,12 @@ int container_create(void *stuff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// run container command
|
// run container command
|
||||||
if (run_subprocess_async(cloneArgs->argv) != 0)
|
if (run_subprocess_async(cloneArgs->argc, cloneArgs->argv) != 0)
|
||||||
{
|
{
|
||||||
error_handler_container(c, "failed to execvp arguments");
|
error_handler_container(c, "failed to execvp arguments");
|
||||||
}
|
}
|
||||||
|
|
||||||
free(c); // free twice don't know why but maybe clone lost
|
free(c); // free twice don't know why but maybe clone lost c reference
|
||||||
c = NULL;
|
c = NULL;
|
||||||
|
|
||||||
// we end container
|
// we end container
|
||||||
@ -75,7 +75,7 @@ pid_t run_container(container_t *c)
|
|||||||
{
|
{
|
||||||
error_handler_container(c, "failed to run_container clone");
|
error_handler_container(c, "failed to run_container clone");
|
||||||
}
|
}
|
||||||
// lets wait on our child process here before we, the parent, exits
|
// lets wait on our child process here before we, the parent, exit
|
||||||
if (waitpid(pid, NULL, 0) == -1)
|
if (waitpid(pid, NULL, 0) == -1)
|
||||||
{
|
{
|
||||||
error_handler_container(c, "failed to wait pid %d", pid);
|
error_handler_container(c, "failed to wait pid %d", pid);
|
||||||
|
39
src/data.c
39
src/data.c
@ -68,4 +68,43 @@ char *read_infinite_fd(int fd)
|
|||||||
return stdout_buffer;
|
return stdout_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read stdin and write to file descriptor
|
||||||
|
*/
|
||||||
|
void write_infinite_fd(int fd)
|
||||||
|
{
|
||||||
|
char *stdin_buffer = new_array(1024);
|
||||||
|
int x = 0;
|
||||||
|
printf("$ ");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
while ((x = read(STDIN_FILENO, stdin_buffer, sizeof(stdin_buffer))) > 0)
|
||||||
|
{
|
||||||
|
write(fd, stdin_buffer, sizeof(stdin_buffer));
|
||||||
|
init_array(stdin_buffer, sizeof(stdin_buffer));
|
||||||
|
printf("$ ");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
free(stdin_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function use to filter char* array
|
||||||
|
* copy src char* into dst if function is true
|
||||||
|
* Return dst length
|
||||||
|
*/
|
||||||
|
int filter_char_array(int src_length, char **src, char **dst, char_predicate filter_func)
|
||||||
|
{
|
||||||
|
int dst_size = 0;
|
||||||
|
for (int i = 0; i < src_length; i++)
|
||||||
|
{
|
||||||
|
if ((*filter_func)(src[i]))
|
||||||
|
{
|
||||||
|
dst[dst_size] = src[i];
|
||||||
|
dst_size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dst_size;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,6 +12,7 @@ int main(int argc, char *const argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct clone_args cloneArgs;
|
struct clone_args cloneArgs;
|
||||||
|
cloneArgs.argc = argc - 1;
|
||||||
cloneArgs.argv = &argv[1];
|
cloneArgs.argv = &argv[1];
|
||||||
cloneArgs.hostname = "container-hostname";
|
cloneArgs.hostname = "container-hostname";
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "./type.h"
|
#include "./type.h"
|
||||||
|
|
||||||
@ -19,15 +20,20 @@ void error(const char *sys_msg, ...);
|
|||||||
void last_error(const char *sys_msg, ...);
|
void last_error(const char *sys_msg, ...);
|
||||||
|
|
||||||
// system.c
|
// system.c
|
||||||
int run_subprocess_async(char *const *argv);
|
int run_subprocess_async(int argc, char *const *argv);
|
||||||
int run_subprocess(char *const *argv);
|
int run_subprocess(char *const *argv);
|
||||||
int pivot_root(char *mount_dir);
|
int pivot_root(char *mount_dir);
|
||||||
int clean_pivot_root(char *a);
|
int clean_pivot_root(char *a);
|
||||||
void remount();
|
void remount();
|
||||||
|
bool is_interactive(char *str);
|
||||||
|
bool is_not_interactive(char *str);
|
||||||
|
bool contain_interactive(int argc, char *const *argv);
|
||||||
|
|
||||||
// data.c
|
// data.c
|
||||||
char *new_array(size_t size);
|
char *new_array(size_t size);
|
||||||
void init_array(char *arr, size_t size);
|
void init_array(char *arr, size_t size);
|
||||||
char *read_infinite_fd(int fd);
|
char *read_infinite_fd(int fd);
|
||||||
|
void write_infinite_fd(int fd);
|
||||||
|
int filter_char_array(int src_length, char **src, char **dst, char_predicate filter_func);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
81
src/system.c
81
src/system.c
@ -13,6 +13,7 @@
|
|||||||
#include <sys/syscall.h>
|
#include <sys/syscall.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -111,13 +112,21 @@ int run_subprocess(char *const *argv)
|
|||||||
/**
|
/**
|
||||||
* Run external binary into new sub process
|
* Run external binary into new sub process
|
||||||
*/
|
*/
|
||||||
int run_subprocess_async(char *const *argv)
|
int run_subprocess_async(int argc, char *const *argv)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
bool run_interactive = contain_interactive(argc, argv);
|
||||||
|
// if container is running in interactive mode remove "-i" from argv
|
||||||
|
if (run_interactive)
|
||||||
|
{
|
||||||
|
char **dst_argv = (char **)malloc(sizeof(char *) * argc);
|
||||||
|
argc = filter_char_array(argc, (char **)argv, dst_argv, is_not_interactive);
|
||||||
|
argv = dst_argv;
|
||||||
|
}
|
||||||
|
|
||||||
// pipe to permit child => parent comunication
|
// pipe to permit parent => child comunication
|
||||||
int pipefd[2];
|
int pipe_parent_to_child_fd[2];
|
||||||
pipe(pipefd);
|
pipe(pipe_parent_to_child_fd);
|
||||||
|
|
||||||
if ((pid = fork()) == -1)
|
if ((pid = fork()) == -1)
|
||||||
{
|
{
|
||||||
@ -125,13 +134,10 @@ int run_subprocess_async(char *const *argv)
|
|||||||
}
|
}
|
||||||
else if (pid == 0)
|
else if (pid == 0)
|
||||||
{
|
{
|
||||||
close(pipefd[0]); // close reading end in the child
|
close(pipe_parent_to_child_fd[1]); // close writing end in the child
|
||||||
|
|
||||||
printf("[CHILD] : running\n");
|
printf("[CHILD] : running\n");
|
||||||
dup2(pipefd[1], 1); // send stdout to the pipe
|
dup2(pipe_parent_to_child_fd[0], STDIN_FILENO); // send pipe to the stdin
|
||||||
dup2(pipefd[1], 2); // send stderr to the pipe
|
|
||||||
|
|
||||||
close(pipefd[1]); // this descriptor is no longer needed
|
|
||||||
|
|
||||||
errno = execvp(argv[0], argv);
|
errno = execvp(argv[0], argv);
|
||||||
return errno;
|
return errno;
|
||||||
@ -140,20 +146,23 @@ int run_subprocess_async(char *const *argv)
|
|||||||
{
|
{
|
||||||
int child_status;
|
int child_status;
|
||||||
|
|
||||||
close(pipefd[1]); // close the write end of the pipe in the parent
|
close(pipe_parent_to_child_fd[0]); // close the read end of the pipe in the parent
|
||||||
|
|
||||||
|
// if container is running in interactive mode
|
||||||
|
if (run_interactive)
|
||||||
|
{
|
||||||
|
// read stdin write infinity
|
||||||
|
write_infinite_fd(pipe_parent_to_child_fd[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(pipe_parent_to_child_fd[1]); // this descriptor is no longer needed
|
||||||
|
|
||||||
|
// wait child if long task is in progress
|
||||||
waitpid(pid, &child_status, 0);
|
waitpid(pid, &child_status, 0);
|
||||||
if (WIFEXITED(child_status))
|
if (WIFEXITED(child_status))
|
||||||
{
|
{
|
||||||
char *stdout_buffer = read_infinite_fd(pipefd[0]);
|
|
||||||
printf("[PARENT] child stdout : \n%s\n", stdout_buffer);
|
|
||||||
free(stdout_buffer);
|
|
||||||
|
|
||||||
close(pipefd[0]); // close the descriptor is no longer needed
|
|
||||||
|
|
||||||
int es = WEXITSTATUS(child_status);
|
int es = WEXITSTATUS(child_status);
|
||||||
printf("[PARENT] Exit status was %d\n", es);
|
printf("[PARENT] Exit status was %d\n", es);
|
||||||
|
|
||||||
return es;
|
return es;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,4 +170,42 @@ int run_subprocess_async(char *const *argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if char* str is equal to "-i"
|
||||||
|
*/
|
||||||
|
bool is_interactive(char *str)
|
||||||
|
{
|
||||||
|
if (strcmp(str, "-i") == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if char* str is not equal to "-i"
|
||||||
|
* opposite of is_interactive
|
||||||
|
*/
|
||||||
|
bool is_not_interactive(char *str)
|
||||||
|
{
|
||||||
|
return !is_interactive(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if argv char* array contain "-i"
|
||||||
|
*/
|
||||||
|
bool contain_interactive(int argc, char *const *argv)
|
||||||
|
{
|
||||||
|
bool res = false;
|
||||||
|
for (int i = 0; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (is_interactive(argv[i]))
|
||||||
|
{
|
||||||
|
res = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
struct clone_args
|
struct clone_args
|
||||||
{
|
{
|
||||||
|
int argc;
|
||||||
char *const *argv;
|
char *const *argv;
|
||||||
const char *hostname;
|
const char *hostname;
|
||||||
};
|
};
|
||||||
@ -19,4 +20,6 @@ typedef struct container_t
|
|||||||
struct clone_args cloneArgs;
|
struct clone_args cloneArgs;
|
||||||
} container_t;
|
} container_t;
|
||||||
|
|
||||||
|
typedef bool (*char_predicate)(char *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user