[gnome-terminal] Fall back to the homedir when we can't get the current tab's cwd
- From: Christian Persch <chpe src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnome-terminal] Fall back to the homedir when we can't get the current tab's cwd
- Date: Wed, 22 Apr 2009 15:54:19 -0400 (EDT)
commit 49a7538e4645db1e143acb8db824d3dd190a3a3e
Author: Christian Persch <chpe gnome org>
Date: Wed Apr 22 20:14:19 2009 +0200
Fall back to the homedir when we can't get the current tab's cwd
When we can't get the cwd of the process in the terminal when opening a
new tab, fall back to its initial working directory, or $HOME. See
bug #565328.
---
src/terminal-screen.c | 151 ++++++++++++++++++++++++++++++------------------
src/terminal-screen.h | 1 +
src/terminal-window.c | 4 +-
3 files changed, 97 insertions(+), 59 deletions(-)
diff --git a/src/terminal-screen.c b/src/terminal-screen.c
index e6dd61e..adc2cb8 100644
--- a/src/terminal-screen.c
+++ b/src/terminal-screen.c
@@ -183,6 +183,59 @@ static guint n_skey_regexes;
G_DEFINE_TYPE (TerminalScreen, terminal_screen, VTE_TYPE_TERMINAL)
+static char *
+cwd_of_pid (int pid)
+{
+ static const char patterns[][18] = {
+ "/proc/%d/cwd", /* Linux */
+ "/proc/%d/path/cwd", /* Solaris >= 10 */
+ };
+ guint i;
+
+ if (pid == -1)
+ return NULL;
+
+ /* Try to get the working directory using various OS-specific mechanisms */
+ for (i = 0; i < G_N_ELEMENTS (patterns); ++i)
+ {
+ char cwd_file[64];
+ char buf[PATH_MAX + 1];
+ int len;
+
+ g_snprintf (cwd_file, sizeof (cwd_file), patterns[i], pid);
+ len = readlink (cwd_file, buf, sizeof (buf) - 1);
+
+ if (len > 0 && buf[0] == '/')
+ return g_strndup (buf, len);
+
+ /* If that didn't do it, try this hack */
+ if (len <= 0)
+ {
+ char *cwd, *working_dir = NULL;
+
+ cwd = g_get_current_dir ();
+ if (cwd != NULL)
+ {
+ /* On Solaris, readlink returns an empty string, but the
+ * link can be used as a directory, including as a target
+ * of chdir().
+ */
+ if (chdir (cwd_file) == 0)
+ {
+ working_dir = g_get_current_dir ();
+ chdir (cwd);
+ }
+ g_free (cwd);
+ }
+
+ if (working_dir)
+ return working_dir;
+ }
+ }
+
+ return NULL;
+}
+
static void
free_tag_data (TagData *tagdata)
{
@@ -1738,75 +1791,59 @@ terminal_screen_get_dynamic_icon_title (TerminalScreen *screen)
* terminal_screen_get_current_dir:
* @screen:
*
- * Returns: a newly allocated string containing the current working directory
- * of the foreground process in @screen's PTY; or otherwise the initial working
- * directory as set by terminal_screen_new()
+ * Tries to determine the current working directory of the foreground process
+ * in @screen's PTY, falling back to the current working directory of the
+ * primary child.
+ *
+ * Returns: a newly allocated string containing the current working directory,
+ * or %NULL on failure
*/
char*
terminal_screen_get_current_dir (TerminalScreen *screen)
{
- static const char patterns[][18] = {
- "/proc/%d/cwd", /* Linux */
- "/proc/%d/path/cwd", /* Solaris >= 10 */
- };
TerminalScreenPrivate *priv = screen->priv;
- int fgpid;
- guint i;
-
- g_return_val_if_fail (TERMINAL_IS_SCREEN (screen), NULL);
+ char *cwd;
+
+ if (priv->pty_fd != -1) {
+ /* Get the foreground process ID */
+ cwd = cwd_of_pid (tcgetpgrp (priv->pty_fd));
+ if (cwd != NULL)
+ return cwd;
+
+ /* If that didn't work, try falling back to the primary child. See bug #575184. */
+ cwd = cwd_of_pid (priv->child_pid);
+ if (cwd != NULL)
+ return cwd;
+ }
- if (priv->pty_fd == -1)
- return g_strdup (priv->initial_working_directory);
+ return NULL;
+}
- /* Get the foreground process ID */
- fgpid = tcgetpgrp (priv->pty_fd);
+/**
+ * terminal_screen_get_current_dir_with_fallback:
+ * @screen:
+ *
+ * Like terminal_screen_get_current_dir(), but falls back to returning
+ * @screen's initial working directory, with a further fallback to the
+ * user's home directory.
+ *
+ * Returns: a newly allocated string containing the current working directory,
+ * or %NULL on failure
+ */
+char*
+terminal_screen_get_current_dir_with_fallback (TerminalScreen *screen)
+{
+ TerminalScreenPrivate *priv = screen->priv;
+ char *cwd;
- /* If that didn't work, try falling back to the primary child. See bug #575184. */
- if (fgpid == -1)
- fgpid = priv->child_pid;
+ cwd = terminal_screen_get_current_dir (screen);
+ if (cwd != NULL)
+ return cwd;
- if (fgpid == -1)
+ if (priv->initial_working_directory != NULL)
return g_strdup (priv->initial_working_directory);
- /* Try to get the working directory using various OS-specific mechanisms */
- for (i = 0; i < G_N_ELEMENTS (patterns); ++i)
- {
- char cwd_file[64];
- char buf[PATH_MAX + 1];
- int len;
-
- g_snprintf (cwd_file, sizeof (cwd_file), patterns[i], fgpid);
- len = readlink (cwd_file, buf, sizeof (buf) - 1);
-
- if (len > 0 && buf[0] == '/')
- return g_strndup (buf, len);
-
- /* If that didn't do it, try this hack */
- if (len <= 0)
- {
- char *cwd, *working_dir = NULL;
-
- cwd = g_get_current_dir ();
- if (cwd != NULL)
- {
- /* On Solaris, readlink returns an empty string, but the
- * link can be used as a directory, including as a target
- * of chdir().
- */
- if (chdir (cwd_file) == 0)
- {
- working_dir = g_get_current_dir ();
- chdir (cwd);
- }
- g_free (cwd);
- }
-
- if (working_dir)
- return working_dir;
- }
- }
-
- return g_strdup (priv->initial_working_directory);
+ return g_strdup (g_get_home_dir ());
}
void
diff --git a/src/terminal-screen.h b/src/terminal-screen.h
index efd5b3c..8b1e422 100644
--- a/src/terminal-screen.h
+++ b/src/terminal-screen.h
@@ -110,6 +110,7 @@ const char *terminal_screen_get_dynamic_title (TerminalScreen *screen);
const char *terminal_screen_get_dynamic_icon_title (TerminalScreen *screen);
char *terminal_screen_get_current_dir (TerminalScreen *screen);
+char *terminal_screen_get_current_dir_with_fallback (TerminalScreen *screen);
void terminal_screen_set_font (TerminalScreen *screen);
void terminal_screen_set_font_scale (TerminalScreen *screen,
diff --git a/src/terminal-window.c b/src/terminal-window.c
index 188bdd1..05e0af1 100644
--- a/src/terminal-window.c
+++ b/src/terminal-window.c
@@ -2807,7 +2807,7 @@ file_new_window_callback (GtkAction *action,
new_window = terminal_app_new_window (app, gtk_widget_get_screen (GTK_WIDGET (window)));
- new_working_directory = terminal_screen_get_current_dir (priv->active_screen);
+ new_working_directory = terminal_screen_get_current_dir_with_fallback (priv->active_screen);
terminal_app_new_terminal (app, new_window, profile,
NULL, NULL,
new_working_directory,
@@ -2839,7 +2839,7 @@ file_new_tab_callback (GtkAction *action,
if (_terminal_profile_get_forgotten (profile))
return;
- new_working_directory = terminal_screen_get_current_dir (priv->active_screen);
+ new_working_directory = terminal_screen_get_current_dir_with_fallback (priv->active_screen);
terminal_app_new_terminal (app, window, profile,
NULL, NULL,
new_working_directory,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]