qrexec: return remote process status as qrexec-client-vm exit code
This doesn't cover all the cases, because local process could want to receive that value (currently it cant), but I can't think of any simple, *compatible* way to pass it there.
This commit is contained in:
parent
1aa05ebc36
commit
4eb1d72aee
@ -181,16 +181,17 @@ int handle_input(libvchan_t *vchan, int fd, int msg_type)
|
|||||||
/* handle data from vchan and send it to specified FD
|
/* handle data from vchan and send it to specified FD
|
||||||
* Return:
|
* Return:
|
||||||
* -2 - remote process terminated, do not send more data to it
|
* -2 - remote process terminated, do not send more data to it
|
||||||
|
* in this case "status" will be set
|
||||||
* -1 - vchan error occurred
|
* -1 - vchan error occurred
|
||||||
* 0 - EOF received, do not attempt to access this FD again
|
* 0 - EOF received, do not attempt to access this FD again
|
||||||
* 1 - some data processed, call it again when buffer space and more data
|
* 1 - some data processed, call it again when buffer space and more data
|
||||||
* available
|
* available
|
||||||
*/
|
*/
|
||||||
int handle_remote_data(libvchan_t *data_vchan, int stdin_fd)
|
|
||||||
|
int handle_remote_data(libvchan_t *data_vchan, int stdin_fd, int *status)
|
||||||
{
|
{
|
||||||
struct msg_header hdr;
|
struct msg_header hdr;
|
||||||
char buf[MAX_DATA_CHUNK];
|
char buf[MAX_DATA_CHUNK];
|
||||||
int status;
|
|
||||||
|
|
||||||
/* TODO: set stdin_fd to non-blocking mode and handle its buffering */
|
/* TODO: set stdin_fd to non-blocking mode and handle its buffering */
|
||||||
while (libvchan_data_ready(data_vchan) > 0) {
|
while (libvchan_data_ready(data_vchan) > 0) {
|
||||||
@ -245,24 +246,24 @@ int handle_remote_data(libvchan_t *data_vchan, int stdin_fd)
|
|||||||
case MSG_DATA_EXIT_CODE:
|
case MSG_DATA_EXIT_CODE:
|
||||||
/* remote process exited, so there is no sense to send any data
|
/* remote process exited, so there is no sense to send any data
|
||||||
* to it */
|
* to it */
|
||||||
if (hdr.len < sizeof(status))
|
if (hdr.len < sizeof(*status))
|
||||||
status = 255;
|
*status = 255;
|
||||||
else
|
else
|
||||||
memcpy(&status, buf, sizeof(status));
|
memcpy(status, buf, sizeof(*status));
|
||||||
fprintf(stderr, "Remote service process exited with code %d\n", status);
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_child_io(libvchan_t *data_vchan,
|
int process_child_io(libvchan_t *data_vchan,
|
||||||
int stdin_fd, int stdout_fd, int stderr_fd)
|
int stdin_fd, int stdout_fd, int stderr_fd)
|
||||||
{
|
{
|
||||||
fd_set rdset, wrset;
|
fd_set rdset, wrset;
|
||||||
int vchan_fd;
|
int vchan_fd;
|
||||||
sigset_t selectmask;
|
sigset_t selectmask;
|
||||||
int child_process_status = -1;
|
int child_process_status = -1;
|
||||||
|
int remote_process_status = -1;
|
||||||
int ret, max_fd;
|
int ret, max_fd;
|
||||||
struct timespec zero_timeout = { 0, 0 };
|
struct timespec zero_timeout = { 0, 0 };
|
||||||
|
|
||||||
@ -372,7 +373,7 @@ void process_child_io(libvchan_t *data_vchan,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* handle_remote_data will check if any data is available */
|
/* handle_remote_data will check if any data is available */
|
||||||
switch (handle_remote_data(data_vchan, stdin_fd)) {
|
switch (handle_remote_data(data_vchan, stdin_fd, &remote_process_status)) {
|
||||||
case -1:
|
case -1:
|
||||||
handle_vchan_error("read");
|
handle_vchan_error("read");
|
||||||
break;
|
break;
|
||||||
@ -388,16 +389,18 @@ void process_child_io(libvchan_t *data_vchan,
|
|||||||
stdout_fd = -1;
|
stdout_fd = -1;
|
||||||
close(stderr_fd);
|
close(stderr_fd);
|
||||||
stderr_fd = -1;
|
stderr_fd = -1;
|
||||||
/* we do not care for any local process */
|
/* if we do not care for any local process, return remote process code */
|
||||||
return;
|
if (child_process_pid == 0)
|
||||||
|
return remote_process_status;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return child_process_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Behaviour depends on type parameter:
|
/* Behaviour depends on type parameter:
|
||||||
* MSG_SERVICE_CONNECT - create vchan server, pass the data to/from given FDs
|
* MSG_SERVICE_CONNECT - create vchan server, pass the data to/from given FDs
|
||||||
* (stdin_fd, stdout_fd, stderr_fd), then return 0
|
* (stdin_fd, stdout_fd, stderr_fd), then return remote process exit code
|
||||||
* MSG_JUST_EXEC - connect to vchan server, fork+exec process given by cmdline
|
* MSG_JUST_EXEC - connect to vchan server, fork+exec process given by cmdline
|
||||||
* parameter, send artificial exit code "0" (local process can still be
|
* parameter, send artificial exit code "0" (local process can still be
|
||||||
* running), then return 0
|
* running), then return 0
|
||||||
@ -453,7 +456,7 @@ int handle_new_process_common(int type, int connect_domain, int connect_port,
|
|||||||
case MSG_SERVICE_CONNECT:
|
case MSG_SERVICE_CONNECT:
|
||||||
child_process_pid = 0;
|
child_process_pid = 0;
|
||||||
stdout_msg_type = MSG_DATA_STDIN;
|
stdout_msg_type = MSG_DATA_STDIN;
|
||||||
process_child_io(data_vchan, stdin_fd, stdout_fd, stderr_fd);
|
exit_code = process_child_io(data_vchan, stdin_fd, stdout_fd, stderr_fd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
libvchan_close(data_vchan);
|
libvchan_close(data_vchan);
|
||||||
@ -488,12 +491,15 @@ pid_t handle_new_process(int type, int connect_domain, int connect_port,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_data_client(int type, int connect_domain, int connect_port,
|
/* Returns exit code of remote process */
|
||||||
|
int handle_data_client(int type, int connect_domain, int connect_port,
|
||||||
int stdin_fd, int stdout_fd, int stderr_fd)
|
int stdin_fd, int stdout_fd, int stderr_fd)
|
||||||
{
|
{
|
||||||
|
int exit_code;
|
||||||
|
|
||||||
assert(type == MSG_SERVICE_CONNECT);
|
assert(type == MSG_SERVICE_CONNECT);
|
||||||
|
|
||||||
handle_new_process_common(type, connect_domain, connect_port,
|
exit_code = handle_new_process_common(type, connect_domain, connect_port,
|
||||||
NULL, 0, stdin_fd, stdout_fd, stderr_fd);
|
NULL, 0, stdin_fd, stdout_fd, stderr_fd);
|
||||||
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ void do_exec(const char *cmd);
|
|||||||
pid_t handle_new_process(int type,
|
pid_t handle_new_process(int type,
|
||||||
int connect_domain, int connect_port,
|
int connect_domain, int connect_port,
|
||||||
char *cmdline, int cmdline_len);
|
char *cmdline, int cmdline_len);
|
||||||
void handle_data_client(int type,
|
int handle_data_client(int type,
|
||||||
int connect_domain, int connect_port,
|
int connect_domain, int connect_port,
|
||||||
int stdin_fd, int stdout_fd, int stderr_fd);
|
int stdin_fd, int stdout_fd, int stderr_fd);
|
||||||
|
|
||||||
|
@ -154,12 +154,12 @@ int main(int argc, char **argv)
|
|||||||
close(inpipe[0]);
|
close(inpipe[0]);
|
||||||
close(outpipe[1]);
|
close(outpipe[1]);
|
||||||
|
|
||||||
handle_data_client(MSG_SERVICE_CONNECT,
|
ret = handle_data_client(MSG_SERVICE_CONNECT,
|
||||||
exec_params.connect_domain, exec_params.connect_port,
|
exec_params.connect_domain, exec_params.connect_port,
|
||||||
inpipe[1], outpipe[0], -1);
|
inpipe[1], outpipe[0], -1);
|
||||||
|
|
||||||
close(trigger_fd);
|
close(trigger_fd);
|
||||||
waitpid(child_pid, &i, 0);
|
waitpid(child_pid, &i, 0);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user