[vte] lib: Move utility function to the file of its only caller
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte] lib: Move utility function to the file of its only caller
- Date: Mon, 27 Apr 2020 18:51:01 +0000 (UTC)
commit d7a9beeffee2f5177b5fec79cf5cdc8e5bc4f636
Author: Christian Persch <chpe src gnome org>
Date: Mon Apr 27 20:49:04 2020 +0200
lib: Move utility function to the file of its only caller
read_ints is only used in spawn.cc, so move it there. Make a note
that this code is copied from glib.
po/POTFILES.in | 1 +
src/libc-glue.hh | 57 ++++++++++++++++++-----
src/spawn.cc | 125 ++++++++++++++++++++++++++++++++++++++++++++++++---
src/vtespawn.cc | 134 -------------------------------------------------------
src/vtespawn.hh | 8 ----
5 files changed, 166 insertions(+), 159 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 69e94a0a..22dc0f9c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,3 +1,4 @@
src/pty.cc
src/vte.cc
src/vtegtk.cc
+src/spawn.cc
diff --git a/src/libc-glue.hh b/src/libc-glue.hh
index d2a3271b..218ebf22 100644
--- a/src/libc-glue.hh
+++ b/src/libc-glue.hh
@@ -101,18 +101,6 @@ constexpr bool operator!=(FD const& lhs, int rhs) { return !(lhs == rhs); }
/* FD convenience functions */
-static inline int
-fd_dupfd_cloexec(int oldfd,
- int newfd)
-{
- auto fd = int{};
- do {
- fd = fcntl(F_DUPFD_CLOEXEC, oldfd, newfd);
- } while (fd == -1 && errno == EINTR);
-
- return fd;
-}
-
static inline int
fd_get_descriptor_flags(int fd)
{
@@ -152,6 +140,45 @@ fd_change_descriptor_flags(int fd,
return fd_set_descriptor_flags(fd, new_flags);
}
+static inline int
+fd_get_status_flags(int fd)
+{
+ auto flags = int{};
+ do {
+ flags = fcntl(fd, F_GETFL, 0);
+ } while (flags == -1 && errno == EINTR);
+
+ return flags;
+}
+
+static inline int
+fd_set_status_flags(int fd,
+ int flags)
+{
+ auto r = int{};
+ do {
+ r = fcntl(fd, F_SETFL, flags);
+ } while (r == -1 && errno == EINTR);
+
+ return r;
+}
+
+static inline int
+fd_change_status_flags(int fd,
+ int set_flags,
+ int unset_flags)
+{
+ auto const flags = fd_get_status_flags(fd);
+ if (flags == -1)
+ return -1;
+
+ auto const new_flags = (flags | set_flags) & ~unset_flags;
+ if (new_flags == flags)
+ return 0;
+
+ return fd_set_status_flags(fd, new_flags);
+}
+
static inline bool
fd_get_cloexec(int fd)
{
@@ -171,6 +198,12 @@ fd_unset_cloexec(int fd)
return fd_change_descriptor_flags(fd, 0, FD_CLOEXEC);
}
+static inline int
+fd_set_nonblock(int fd)
+{
+ return fd_change_status_flags(fd, O_NONBLOCK, 0);
+}
+
static inline int
fd_dup_cloexec(int oldfd,
int newfd)
diff --git a/src/spawn.cc b/src/spawn.cc
index b8b78311..1e337d1a 100644
--- a/src/spawn.cc
+++ b/src/spawn.cc
@@ -80,6 +80,120 @@ make_pipe(int flags,
return true;
}
+/* Code for read_ints copied from glib/glib/gspawn.c, there under LGPL2.1+,
+ * and used here under LGPL3+.
+ *
+ * Copyright 2000 Red Hat, Inc.
+ */
+static bool
+read_ints(int fd,
+ int* buf,
+ int n_ints_in_buf,
+ int *n_ints_read,
+ int timeout,
+ GPollFD *cancellable_pollfd,
+ vte::glib::Error& error)
+{
+ GPollFD pollfds[2];
+ auto n_pollfds = unsigned{0};
+
+ if (timeout >= 0 || cancellable_pollfd != nullptr) {
+ if (vte::libc::fd_set_nonblock(fd) < 0) {
+ auto errsv = vte::libc::ErrnoSaver{};
+ error.set(G_IO_ERROR, g_io_error_from_errno(errsv),
+ _("Failed to set pipe nonblocking: %s"), g_strerror(errsv));
+ return false;
+ }
+
+ pollfds[0].fd = fd;
+ pollfds[0].events = G_IO_IN | G_IO_HUP | G_IO_ERR;
+ n_pollfds = 1;
+
+ if (cancellable_pollfd != nullptr) {
+ pollfds[1] = *cancellable_pollfd;
+ n_pollfds = 2;
+ }
+ } else
+ n_pollfds = 0;
+
+ auto start_time = int64_t{0};
+ if (timeout >= 0)
+ start_time = g_get_monotonic_time();
+
+ auto bytes = size_t{0};
+ while (true) {
+ if (bytes >= sizeof(int)*2)
+ break; /* give up, who knows what happened, should not be
+ * possible.
+ */
+
+ again:
+ if (n_pollfds != 0) {
+ pollfds[0].revents = pollfds[1].revents = 0;
+
+ auto const r = g_poll(pollfds, n_pollfds, timeout);
+
+ /* Update timeout */
+ if (timeout >= 0) {
+ timeout -= (g_get_monotonic_time () - start_time) / 1000;
+ if (timeout < 0)
+ timeout = 0;
+ }
+
+ if (r < 0 && errno == EINTR)
+ goto again;
+ if (r < 0) {
+ auto errsv = vte::libc::ErrnoSaver{};
+ error.set(G_IO_ERROR, g_io_error_from_errno(errsv),
+ _("poll error: %s"), g_strerror(errsv));
+ return false;
+ }
+ if (r == 0) {
+ auto errsv = vte::libc::ErrnoSaver{};
+ error.set_literal(G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
+ _("Operation timed out"));
+ return false;
+ }
+
+ /* If the passed-in poll FD becomes readable, that's the signal
+ * to cancel the operation. We do NOT actually read from its FD!
+ */
+ if (n_pollfds == 2 && pollfds[1].revents) {
+ auto errsv = vte::libc::ErrnoSaver{};
+ error.set_literal(G_IO_ERROR, G_IO_ERROR_CANCELLED,
+ _("Operation was cancelled"));
+ return false;
+ }
+
+ /* Now we know we can try to read from the child */
+ }
+
+ auto const chunk = read(fd,
+ ((char*)buf) + bytes,
+ sizeof(int) * n_ints_in_buf - bytes);
+ if (chunk < 0 && errno == EINTR)
+ goto again;
+
+ if (chunk < 0) {
+ auto errsv = vte::libc::ErrnoSaver{};
+
+ /* Some weird shit happened, bail out */
+ error.set(G_IO_ERROR, g_io_error_from_errno(errsv),
+ _("Failed to read from child pipe (%s)"),
+ g_strerror(errsv));
+
+ return false;
+ } else if (chunk == 0)
+ break; /* EOF */
+ else /* chunk > 0 */
+ bytes += chunk;
+ }
+
+ *n_ints_read = int(bytes / sizeof(int));
+
+ return true;
+}
+
static char**
merge_environ(char** envp /* consumed */,
char const* cwd,
@@ -437,11 +551,12 @@ SpawnOperation::run(vte::glib::Error& error) noexcept
g_assert_cmpint(m_child_report_error_pipe_read.get(), !=, -1);
assert(m_child_report_error_pipe_read);
- if (!_vte_read_ints(m_child_report_error_pipe_read.get(),
- buf, 2, &n_read,
- m_timeout,
- &m_cancellable_pollfd,
- error))
+ if (!read_ints(m_child_report_error_pipe_read.get(),
+ buf, 2,
+ &n_read,
+ m_timeout,
+ &m_cancellable_pollfd,
+ error))
return false;
if (n_read >= 2) {
diff --git a/src/vtespawn.cc b/src/vtespawn.cc
index 662968be..2bb285a3 100644
--- a/src/vtespawn.cc
+++ b/src/vtespawn.cc
@@ -73,17 +73,6 @@ _vte_write_err (int fd,
write_all(fd, data, sizeof(data));
}
-static int
-fd_set_nonblocking(int fd)
-{
- int flags = fcntl(fd, F_GETFL, 0);
- if (flags < 0)
- return -1;
- if ((flags & O_NONBLOCK) != 0)
- return 0;
- return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
-}
-
G_GNUC_UNUSED static int
close_func (void *data, int fd)
{
@@ -93,129 +82,6 @@ close_func (void *data, int fd)
return 0;
}
-bool
-_vte_read_ints(int fd,
- int* buf,
- int n_ints_in_buf,
- int *n_ints_read,
- int timeout,
- GPollFD *cancellable_pollfd,
- GError **error)
-{
- gsize bytes = 0;
- GPollFD pollfds[2];
- guint n_pollfds;
- int64_t start_time = 0;
-
- if (timeout >= 0 || cancellable_pollfd != nullptr)
- {
- if (fd_set_nonblocking(fd) < 0)
- {
- int errsv = errno;
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
- _("Failed to set pipe nonblocking: %s"), g_strerror (errsv));
- return false;
- }
-
- pollfds[0].fd = fd;
- pollfds[0].events = G_IO_IN | G_IO_HUP | G_IO_ERR;
- n_pollfds = 1;
-
- if (cancellable_pollfd != NULL)
- {
- pollfds[1] = *cancellable_pollfd;
- n_pollfds = 2;
- }
- }
- else
- n_pollfds = 0;
-
- if (timeout >= 0)
- start_time = g_get_monotonic_time ();
-
- while (true)
- {
- gssize chunk;
-
- if (bytes >= sizeof(int)*2)
- break; /* give up, who knows what happened, should not be
- * possible.
- */
-
- again:
- if (n_pollfds != 0)
- {
- int r;
-
- pollfds[0].revents = pollfds[1].revents = 0;
-
- r = g_poll (pollfds, n_pollfds, timeout);
-
- /* Update timeout */
- if (timeout >= 0)
- {
- timeout -= (g_get_monotonic_time () - start_time) / 1000;
- if (timeout < 0)
- timeout = 0;
- }
-
- if (r < 0 && errno == EINTR)
- goto again;
- if (r < 0)
- {
- int errsv = errno;
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
- _("poll error: %s"), g_strerror (errsv));
- return false;
- }
- if (r == 0)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
- _("Operation timed out"));
- return false;
- }
-
- /* If the passed-in poll FD becomes readable, that's the signal
- * to cancel the operation. We do NOT actually read from its FD!
- */
- if (n_pollfds == 2 && pollfds[1].revents)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
- _("Operation was cancelled"));
- return false;
- }
-
- /* Now we know we can try to read from the child */
- }
-
- chunk = read (fd,
- ((char*)buf) + bytes,
- sizeof(int) * n_ints_in_buf - bytes);
- if (chunk < 0 && errno == EINTR)
- goto again;
-
- if (chunk < 0)
- {
- int errsv = errno;
-
- /* Some weird shit happened, bail out */
- g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
- _("Failed to read from child pipe (%s)"),
- g_strerror (errsv));
-
- return false;
- }
- else if (chunk == 0)
- break; /* EOF */
- else /* chunk > 0 */
- bytes += chunk;
- }
-
- *n_ints_read = int(bytes / sizeof(int));
-
- return true;
-}
-
/* Based on execvp from GNU C Library */
static void
diff --git a/src/vtespawn.hh b/src/vtespawn.hh
index 908fcbe9..481929cf 100644
--- a/src/vtespawn.hh
+++ b/src/vtespawn.hh
@@ -28,13 +28,5 @@ int _vte_execute(char const* file,
bool search_path,
bool search_path_from_envp);
-bool _vte_read_ints(int fd,
- int* buf,
- int n_ints_in_buf,
- int *n_ints_read,
- int timeout,
- GPollFD *cancellable_pollfd,
- GError **error);
-
void _vte_write_err (int fd,
int msg);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]