11
11
#include <string.h>
12
12
#include <unistd.h>
13
13
#include <libkrun.h>
14
+ #include <getopt.h>
15
+ #include <stdbool.h>
16
+ #include <assert.h>
14
17
15
18
#define MAX_ARGS_LEN 4096
16
19
#ifndef MAX_PATH
17
20
#define MAX_PATH 4096
18
21
#endif
19
22
23
+ static void print_help (char * const name )
24
+ {
25
+ fprintf (stderr ,
26
+ "Usage: %s [OPTIONS] NEWROOT COMMAND [COMMAND_ARGS...]\n"
27
+ "OPTIONS: \n"
28
+ " -h --help Show help\n"
29
+ "\n"
30
+ "NEWROOT: the root directory of the vm\n"
31
+ "COMMAND: the command you want to execute in the vm\n"
32
+ "COMMAND_ARGS: arguments of COMMAND\n" ,
33
+ name
34
+ );
35
+ }
36
+
37
+ static const struct option long_options [] = {
38
+ { "help" , no_argument , NULL , 'h' },
39
+ { NULL , 0 , NULL , 0 }
40
+ };
41
+
42
+ struct cmdline {
43
+ bool show_help ;
44
+ char const * new_root ;
45
+ char * const * guest_argv ;
46
+ };
47
+
48
+ bool parse_cmdline (int argc , char * const argv [], struct cmdline * cmdline )
49
+ {
50
+ assert (cmdline != NULL );
51
+
52
+ // set the defaults
53
+ * cmdline = (struct cmdline ){
54
+ .show_help = false,
55
+ .new_root = NULL ,
56
+ .guest_argv = NULL ,
57
+ };
58
+
59
+ int option_index = 0 ;
60
+ int c ;
61
+ // the '+' in optstring is a GNU extension that disables permutating argv
62
+ while ((c = getopt_long (argc , argv , "+h" , long_options , & option_index )) != -1 ) {
63
+ switch (c ) {
64
+ case 'h' :
65
+ cmdline -> show_help = true;
66
+ return true;
67
+ case '?' :
68
+ return false;
69
+ default :
70
+ fprintf (stderr , "internal argument parsing error (returned character code 0x%x)\n" , c );
71
+ return false;
72
+ }
73
+ }
74
+
75
+ if (optind <= argc - 2 ) {
76
+ cmdline -> new_root = argv [optind ];
77
+ cmdline -> guest_argv = & argv [optind + 1 ];
78
+ return true;
79
+ }
80
+
81
+ if (optind >= argc - 1 ) {
82
+ fprintf (stderr , "Missing COMMAND argument\n" );
83
+ }
84
+
85
+ if (optind == argc ) {
86
+ fprintf (stderr , "Missing NEWROOT argument\n" );
87
+ }
88
+
89
+ return false;
90
+ }
91
+
92
+
20
93
int main (int argc , char * const argv [])
21
94
{
22
95
char * const envp [] =
@@ -43,13 +116,19 @@ int main(int argc, char *const argv[])
43
116
int ctx_id ;
44
117
int err ;
45
118
int i ;
119
+ struct cmdline cmdline ;
46
120
47
- if (argc < 3 ) {
48
- printf ( "Invalid arguments\n" );
49
- printf ( "Usage: %s NEWROOT COMMAND [ARG...]\n" , argv [0 ]);
121
+ if (! parse_cmdline ( argc , argv , & cmdline ) ) {
122
+ putchar ( '\n' );
123
+ print_help ( argv [0 ]);
50
124
return -1 ;
51
125
}
52
126
127
+ if (cmdline .show_help ){
128
+ print_help (argv [0 ]);
129
+ return 0 ;
130
+ }
131
+
53
132
// Set the log level to "off".
54
133
err = krun_set_log_level (0 );
55
134
if (err ) {
@@ -73,8 +152,7 @@ int main(int argc, char *const argv[])
73
152
return -1 ;
74
153
}
75
154
76
- // Use the first command line argument as the path to be used as root.
77
- if (err = krun_set_root (ctx_id , argv [1 ])) {
155
+ if (err = krun_set_root (ctx_id , cmdline .new_root )) {
78
156
errno = - err ;
79
157
perror ("Error configuring root path" );
80
158
return -1 ;
@@ -125,9 +203,8 @@ int main(int argc, char *const argv[])
125
203
return -1 ;
126
204
}
127
205
128
- // Use the second argument as the path of the binary to be executed in the isolated
129
- // context, relative to the root path.
130
- if (err = krun_set_exec (ctx_id , argv [2 ], & argv [3 ], & envp [0 ])) {
206
+ // Specify the path of the binary to be executed in the isolated context, relative to the root path.
207
+ if (err = krun_set_exec (ctx_id , cmdline .guest_argv [0 ], & cmdline .guest_argv [1 ], & envp [0 ])) {
131
208
errno = - err ;
132
209
perror ("Error configuring the parameters for the executable to be run" );
133
210
return -1 ;
0 commit comments