1717
1818// wsl_wrapper: wrapper for WSL apps on Windows.
1919//
20- // cmdline options:
20+ // wsl_wrapper [options] arg1 arg2
21+ // arg1 arg2 ... are passed to the main program on cmdline
22+ // options:
2123//
2224// --main_prog X name of main program (default "main")
23- // --pass_thru args additional cmdline arg for main program
2425// --os_name_regex use only distros w/ matching OS name
2526// --os_version_regex
2627// --min_libc_version MMmm e.g. 235 means 2.35
3435// and relays this to the client.
3536
3637// implementation:
37- // We use two WSL_CMDs (connections into the WSL container):
38- // one to run the app, get its process group ID,
38+ // We use two WSL_CMDs (connections to shells the WSL container):
39+ // app_wc: run the app, get its process group ID,
3940// and capture its stdout and stderr
40- // another to run a shell for monitoring and control operations (ps, kill)
41- // ( this has less overhead than creating a shell per op)
41+ // ctl_wc: monitoring and control operations (ps, kill)
42+ // this has less overhead than creating a shell per op
4243//
4344// Typically, the app has a control script as well as an executable.
4445// This might be written in bash or perl,
5758
5859#include < cstdio>
5960#include < string>
61+ #include < vector>
6062
6163#include " boinc_win.h"
6264#include " util.h"
6567#include " app_ipc.h"
6668
6769using std::string;
70+ using std::vector;
6871
6972WSL_CMD app_wc;
7073WSL_CMD ctl_wc;
@@ -110,8 +113,8 @@ int launch(const char* distro, const char* cmd) {
110113 retval = read_from_pipe (app_wc.out_read , app_wc.proc_handle , reply, CMD_TIMEOUT, " \n " );
111114 if (retval) return error (" app read_from_pipe" , retval);
112115 pgid = atoi (reply.c_str ());
116+ fprintf (stderr, " launch reply: [%s]\n " , reply.c_str ());
113117 if (verbose) {
114- fprintf (stderr, " launch reply: [%s]\n " , reply.c_str ());
115118 fprintf (stderr, " pgid: %d\n " , pgid);
116119 }
117120 running = true ;
@@ -223,36 +226,48 @@ void poll_client_msgs() {
223226 }
224227}
225228
229+ // copy app_wc to our stderr;
230+ // called when job finishes
231+ //
232+ void copy_output () {
233+ string reply;
234+ read_from_pipe (
235+ app_wc.out_read , app_wc.proc_handle , reply, CMD_TIMEOUT, NULL
236+ );
237+ fprintf (stderr, " output from container:\n %s\n " , reply.c_str ());
238+ }
239+
226240int main (int argc, char ** argv) {
227- const char *os_name_regexp=" .*" , *os_version_regexp=" .*" , *pass_thru= NULL ;
241+ const char *os_name_regexp=" .*" , *os_version_regexp=" .*" ;
228242 const char *main_prog = " main" ;
229243 int min_libc_version = 0 ;
244+ vector<string> app_args;
245+
246+ // do this before writing to stderr, else the messages will be lost
247+ //
248+ BOINC_OPTIONS options;
249+ memset (&options, 0 , sizeof (options));
250+ options.main_program = true ;
251+ options.check_heartbeat = true ;
252+ options.handle_process_control = true ;
253+ boinc_init_options (&options);
254+
230255 for (int i=1 ; i<argc; i++) {
231256 if (!strcmp (argv[i], " --os_name_regexp" )) {
232257 os_name_regexp = argv[++i];
233258 } else if (!strcmp (argv[i], " --os_version_regexp" )) {
234259 os_version_regexp = argv[++i];
235- } else if (!strcmp (argv[i], " --pass_thru" )) {
236- pass_thru = argv[++i];
237260 } else if (!strcmp (argv[i], " --min_libc_version" )) {
238261 min_libc_version = atoi (argv[++i]);
239262 } else if (!strcmp (argv[i], " --verbose" )) {
240263 verbose = true ;
241264 } else if (!strcmp (argv[i], " --main_prog" )) {
242265 main_prog = argv[++i];
243266 } else {
244- fprintf (stderr, " unknown option %s\n " , argv[i]);
245- exit (1 );
267+ app_args.push_back (argv[i]);
246268 }
247269 }
248270
249- BOINC_OPTIONS options;
250- memset (&options, 0 , sizeof (options));
251- options.main_program = true ;
252- options.check_heartbeat = true ;
253- options.handle_process_control = true ;
254- boinc_init_options (&options);
255-
256271 string distro_name;
257272 if (boinc_is_standalone ()) {
258273 SetCurrentDirectoryA (" C:/ProgramData/BOINC/slots/test" );
@@ -271,9 +286,9 @@ int main(int argc, char** argv) {
271286
272287 string main_cmd = " ./" ;
273288 main_cmd += main_prog;
274- if (pass_thru) {
289+ for (string s: app_args) {
275290 main_cmd += " " ;
276- main_cmd += pass_thru ;
291+ main_cmd += s ;
277292 }
278293 if (launch (distro_name.c_str (), main_cmd.c_str ())) {
279294 fprintf (stderr, " launch failed\n " );
@@ -287,10 +302,12 @@ int main(int argc, char** argv) {
287302 switch (poll_app (ru)) {
288303 case JOB_FAIL:
289304 fprintf (stderr, " job failed\n " );
305+ copy_output ();
290306 boinc_finish (1 );
291307 goto done;
292308 case JOB_SUCCESS:
293309 fprintf (stderr, " job succeeded\n " );
310+ copy_output ();
294311 boinc_finish (0 );
295312 goto done;
296313 }
0 commit comments