Bug#241485: libvte4: [PATCH] please add vte_terminal_fork_pty()
Michael Vogt
Michael Vogt <mvogt@acm.org>, 241485@bugs.debian.org
Thu, 01 Apr 2004 17:00:14 +0200
This is a multi-part MIME message sent by reportbug.
--===============1541456203==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Package: libvte4
Version: 1:0.11.10-6
Severity: wishlist
Tags: patch
Please add the attached patch to libvte4. This patch is taken from
the current vte cvs. It will make it possible for synaptic (and other
applications) to use vte instead of zvt. Having to use zvt because of
the missing fork_pty() support in vte is a huge pain because zvt is
_very_ buggy and causes segfaults for certain LANG settings.
The patch is done very carefull and only touches vte.{c,h} and pty.c. In
vte.c only vte_terminal_fork_pty() is added, no existing code is
touched.
pty.c is a bit more tricky. Existing code is modified. But I'm sure that
the code is safe too. The first chunk move the old code inside
"if(command!=NULL)" which is always true if it is called from
vte_terminal_fork_command(). The last chunk is also safe as argc > 1
is always true if called from vte_terminal_fork_command(). If
fork_command() is called without a command then the shell is used.
(see vte.c:6946).
I tested this patch with gnome-terminal and with the fork_pty() enabled
version of synaptic and it seems to work well. If there is anything more
I can do to convince you to apply this patch, please tell me :)
I would really love to kick libzvt as a dependency from synaptic and
make it vte instead.
thanks,
Michael
-- System Information:
Debian Release: testing/unstable
APT prefers unstable
APT policy: (500, 'unstable')
Architecture: i386 (i686)
Kernel: Linux 2.4.25
Locale: LANG=C, LC_CTYPE=de_DE
Versions of packages libvte4 depends on:
ii libatk1.0-0 1.4.1-1 The ATK accessibility toolkit
ii libc6 2.3.2.ds1-11 GNU C Library: Shared libraries an
ii libfontconfig1 2.2.2-1 generic font configuration library
ii libfreetype6 2.1.7-2 FreeType 2 font engine, shared lib
ii libglib2.0-0 2.2.3-1 The GLib library of C routines
ii libgtk2.0-0 2.2.4-3 The GTK+ graphical user interface
ii libice6 4.3.0-7 Inter-Client Exchange library
ii libncurses5 5.4-3 Shared libraries for terminal hand
ii libpango1.0-0 1.2.5-2.1 Layout and rendering of internatio
ii libsm6 4.3.0-7 X Window System Session Management
ii libvte-common 1:0.11.10-6 Terminal emulator widget for GTK+
ii libx11-6 4.3.0-7 X Window System protocol client li
ii libxft2 2.1.2-6 FreeType-based font drawing librar
ii libxrender1 0.8.3-7 X Rendering Extension client libra
ii xlibs 4.3.0-7 X Window System client libraries m
ii zlib1g 1:1.2.1-5 compression library - runtime
-- no debconf information
--===============1541456203==
Content-Type: text/x-c; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="vte-fork-pty.diff"
--- vte-0.11.10.orig/src/vte.h
+++ vte-0.11.10/src/vte.h
@@ -158,6 +158,13 @@
gboolean utmp,
gboolean wtmp);
+/* Users of libzvt may find this useful. */
+pid_t vte_terminal_forkpty(VteTerminal *terminal,
+ char **envv, const char *directory,
+ gboolean lastlog,
+ gboolean utmp,
+ gboolean wtmp);
+
/* Send data to the terminal to display, or to the terminal's forked command
* to handle in some way. If it's 'cat', they should be the same. */
void vte_terminal_feed(VteTerminal *terminal, const char *data, glong length);
--- vte-0.11.10.orig/src/vte.c
+++ vte-0.11.10/src/vte.c
@@ -6791,6 +6791,122 @@
}
/**
+ * vte_terminal_forkpty:
+ * @terminal: a #VteTerminal
+ * @envv: a list of environment variables to be added to the environment before
+ * starting returning in the child process, or NULL
+ * @directory: the name of a directory the child process should change to, or
+ * NULL
+ * @lastlog: TRUE if the session should be logged to the lastlog
+ * @utmp: TRUE if the session should be logged to the utmp/utmpx log
+ * @wtmp: TRUE if the session should be logged to the wtmp/wtmpx log
+ *
+ * Starts a new child process under a newly-allocated controlling
+ * pseudo-terminal. TERM is automatically set to reflect the terminal widget's
+ * emulation setting. If @lastlog, @utmp, or @wtmp are TRUE, logs the session
+ * to the specified system log files.
+ *
+ * Returns: the ID of the new process in the parent, 0 in the child, and -1 if
+ * there was an error
+ *
+ * Since: 0.11.11
+ */
+pid_t
+vte_terminal_forkpty(VteTerminal *terminal,
+ char **envv, const char *directory,
+ gboolean lastlog, gboolean utmp, gboolean wtmp)
+{
+ char **env_add;
+ int i;
+ pid_t pid;
+ GtkWidget *widget;
+ VteReaper *reaper;
+
+ g_return_val_if_fail(VTE_IS_TERMINAL(terminal), -1);
+
+/* ret = _vte_terminal_fork_basic(terminal, NULL, NULL, envv, */
+/* directory, lastlog, utmp, wtmp); */
+ widget = GTK_WIDGET(terminal);
+
+ /* Duplicate the environment, and add one more variable. */
+ for (i = 0; (envv != NULL) && (envv[i] != NULL); i++) {
+ /* nothing */ ;
+ }
+ env_add = g_malloc0(sizeof(char*) * (i + 2));
+ env_add[0] = g_strdup_printf("TERM=%s", terminal->pvt->emulation);
+ for (i = 0; (envv != NULL) && (envv[i] != NULL); i++) {
+ env_add[i + 1] = g_strdup(envv[i]);
+ }
+ env_add[i + 1] = NULL;
+
+ /* Close any existing ptys. */
+ if (terminal->pvt->pty_master != -1) {
+ _vte_pty_close(terminal->pvt->pty_master);
+ close(terminal->pvt->pty_master);
+ }
+
+ /* Open the new pty. */
+ pid = -1;
+ i = _vte_pty_open(&pid, env_add, NULL, NULL, directory,
+ terminal->column_count, terminal->row_count,
+ lastlog, utmp, wtmp);
+ switch (i) {
+ case -1:
+ return -1;
+ break;
+ default:
+ if (pid != 0) {
+ terminal->pvt->pty_master = i;
+ }
+ }
+
+ /* If we successfully started the process, set up to listen for its
+ * output. */
+ if ((pid != -1) && (pid != 0)) {
+ /* Set this as the child's pid. */
+ terminal->pvt->pty_pid = pid;
+
+ /* Catch a child-exited signal from the child pid. */
+ reaper = vte_reaper_get();
+ g_object_ref(G_OBJECT(reaper));
+ if (VTE_IS_REAPER(terminal->pvt->pty_reaper)) {
+ g_signal_handlers_disconnect_by_func(terminal->pvt->pty_reaper,
+ (gpointer)vte_terminal_catch_child_exited,
+ terminal);
+ g_object_unref(G_OBJECT(terminal->pvt->pty_reaper));
+ }
+ g_signal_connect(G_OBJECT(reaper), "child-exited",
+ G_CALLBACK(vte_terminal_catch_child_exited),
+ terminal);
+ terminal->pvt->pty_reaper = reaper;
+
+ /* Set the pty to be non-blocking. */
+ i = fcntl(terminal->pvt->pty_master, F_GETFL);
+ fcntl(terminal->pvt->pty_master, F_SETFL, i | O_NONBLOCK);
+
+ /* Set the PTY size. */
+ vte_terminal_set_size(terminal,
+ terminal->column_count,
+ terminal->row_count);
+ if (GTK_WIDGET_REALIZED(widget)) {
+ gtk_widget_queue_resize(widget);
+ }
+
+ /* Open a channel to listen for input on. */
+ _vte_terminal_connect_pty_read(terminal);
+ }
+
+ /* Clean up. */
+ for (i = 0; env_add[i] != NULL; i++) {
+ g_free(env_add[i]);
+ }
+ g_free(env_add);
+
+ return pid;
+}
+
+
+/**
* vte_terminal_fork_command:
* @terminal: a #VteTerminal
* @command: the name of a binary to run
--- vte-0.11.10.orig/src/pty.c
+++ vte-0.11.10/src/pty.c
@@ -362,23 +362,26 @@
close(ready_reader);
}
- /* Outta here. */
- if (argv != NULL) {
- for (i = 0; (argv[i] != NULL); i++) ;
- args = g_malloc0(sizeof(char*) * (i + 1));
- for (i = 0; (argv[i] != NULL); i++) {
- args[i] = g_strdup(argv[i]);
- }
- execvp(command, args);
- } else {
- arg = g_strdup(command);
- execlp(command, arg, NULL);
- }
-
- /* Avoid calling any atexit() code. */
- _exit(0);
- g_assert_not_reached();
- return 0;
+ /* If the caller provided a command, we can't go back, ever. */
+ if (command != NULL) {
+ /* Outta here. */
+ if (argv != NULL) {
+ for (i = 0; (argv[i] != NULL); i++) ;
+ args = g_malloc0(sizeof(char*) * (i + 1));
+ for (i = 0; (argv[i] != NULL); i++) {
+ args[i] = g_strdup(argv[i]);
+ }
+ execvp(command, args);
+ } else {
+ arg = g_strdup(command);
+ execlp(command, arg, NULL);
+ }
+
+ /* Avoid calling any atexit() code. */
+ _exit(0);
+ g_assert_not_reached();
+ }
+ return 0;
}
/* Open the named PTY slave, fork off a child (storing its PID in child),
@@ -469,6 +472,9 @@
/* TIOCSCTTY is defined? Let's try that, too. */
ioctl(fd, TIOCSCTTY, fd);
#endif
+ /* Store 0 as the "child"'s ID to indicate to the caller that
+ * it is now the child. */
+ *child = 0;
return _vte_pty_run_on_pty(fd, ready_b[0], ready_a[1],
env_add, command, argv, directory);
}
@@ -569,6 +575,9 @@
#endif
}
+ /* Store 0 as the "child"'s ID to indicate to the caller that
+ * it is now the child. */
+ *child = 0;
return _vte_pty_run_on_pty(fd, ready_b[0], ready_a[1],
env_add, command, argv, directory);
}
@@ -1140,7 +1149,7 @@
signal(SIGCHLD, sigchld_handler);
_vte_debug_parse_string(getenv("VTE_DEBUG_FLAGS"));
fd = _vte_pty_open(&child, NULL,
- (argc > 1) ? argv[1] : "/usr/bin/tty",
+ (argc > 1) ? argv[1] : NULL,
(argc > 1) ? argv + 1 : NULL,
NULL,
0, 0,
--===============1541456203==--