diff options
Diffstat (limited to 'src/core/nm-core-utils.c')
-rw-r--r-- | src/core/nm-core-utils.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/core/nm-core-utils.c b/src/core/nm-core-utils.c index 2c251855bf..15b3c6a80a 100644 --- a/src/core/nm-core-utils.c +++ b/src/core/nm-core-utils.c @@ -4866,11 +4866,14 @@ typedef struct { int child_stdin; int child_stdout; + int child_stderr; GSource *input_source; GSource *output_source; + GSource *error_source; NMStrBuf in_buffer; NMStrBuf out_buffer; + NMStrBuf err_buffer; gsize out_buffer_offset; } HelperInfo; @@ -4906,13 +4909,17 @@ helper_info_free(gpointer data) nm_str_buf_destroy(&info->in_buffer); nm_str_buf_destroy(&info->out_buffer); + nm_str_buf_destroy(&info->err_buffer); nm_clear_g_source_inst(&info->input_source); nm_clear_g_source_inst(&info->output_source); + nm_clear_g_source_inst(&info->error_source); if (info->child_stdout != -1) nm_close(info->child_stdout); if (info->child_stdin != -1) nm_close(info->child_stdin); + if (info->child_stderr != -1) + nm_close(info->child_stderr); if (info->pid != -1) { nm_assert(info->pid > 1); @@ -4926,6 +4933,10 @@ static void helper_complete(HelperInfo *info, GError *error) { if (error) { + if (info->err_buffer.len > 0) { + _LOG2T(info, "stderr: %s", nm_str_buf_get_str(&info->err_buffer)); + } + nm_clear_g_cancellable_disconnect(g_task_get_cancellable(info->task), &info->cancellable_id); g_task_return_error(info->task, error); @@ -5021,6 +5032,24 @@ helper_have_data(int fd, GIOCondition condition, gpointer user_data) return G_SOURCE_CONTINUE; } +static gboolean +helper_have_err_data(int fd, GIOCondition condition, gpointer user_data) +{ + HelperInfo *info = user_data; + gssize n_read; + + n_read = nm_utils_fd_read(fd, &info->err_buffer); + + if (n_read > 0) + return G_SOURCE_CONTINUE; + + nm_clear_g_source_inst(&info->error_source); + nm_close(info->child_stderr); + info->child_stderr = -1; + + return G_SOURCE_CONTINUE; +} + static void helper_child_terminated(GPid pid, int status, gpointer user_data) { @@ -5096,10 +5125,11 @@ nm_utils_spawn_helper(const char *const *args, &info->pid, &info->child_stdin, &info->child_stdout, - NULL, + &info->child_stderr, &error)) { info->child_stdin = -1; info->child_stdout = -1; + info->child_stderr = -1; info->pid = -1; g_task_return_error(info->task, g_error_new(NM_UTILS_ERROR, @@ -5128,6 +5158,8 @@ nm_utils_spawn_helper(const char *const *args, fcntl(info->child_stdin, F_SETFL, fd_flags | O_NONBLOCK); fd_flags = fcntl(info->child_stdout, F_GETFD, 0); fcntl(info->child_stdout, F_SETFL, fd_flags | O_NONBLOCK); + fd_flags = fcntl(info->child_stderr, F_GETFD, 0); + fcntl(info->child_stderr, F_SETFL, fd_flags | O_NONBLOCK); /* Watch process stdin */ info->out_buffer = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_40, TRUE); @@ -5153,6 +5185,16 @@ nm_utils_spawn_helper(const char *const *args, NULL); g_source_attach(info->input_source, g_main_context_get_thread_default()); + /* Watch process stderr */ + info->err_buffer = NM_STR_BUF_INIT(0, FALSE); + info->error_source = nm_g_unix_fd_source_new(info->child_stderr, + G_IO_IN | G_IO_ERR | G_IO_HUP, + G_PRIORITY_DEFAULT, + helper_have_err_data, + info, + NULL); + g_source_attach(info->error_source, g_main_context_get_thread_default()); + if (cancellable) { gulong signal_id; |