diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2011-01-04 16:05:11 +0000 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2011-01-04 16:18:27 +0000 |
commit | 7ce627fce02eae8c7db36b4090fa0ce1bf69bf44 (patch) | |
tree | 035da8f420996286459dc118bb879b01e6f4d9ee /fish | |
parent | a9802509184341e731de5c9af363184a9964a8a7 (diff) | |
download | libguestfs-7ce627fce02eae8c7db36b4090fa0ce1bf69bf44.tar.gz libguestfs-7ce627fce02eae8c7db36b4090fa0ce1bf69bf44.tar.xz libguestfs-7ce627fce02eae8c7db36b4090fa0ce1bf69bf44.zip |
fish: fails to tilde expand '~' when $HOME env is unset (RHBZ#617440).
This also adds a regression test.
Diffstat (limited to 'fish')
-rw-r--r-- | fish/tilde.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/fish/tilde.c b/fish/tilde.c index 806297c5..ee87ce1b 100644 --- a/fish/tilde.c +++ b/fish/tilde.c @@ -28,8 +28,9 @@ #include "fish.h" -static char *expand_home (const char *); +static char *expand_home (char *orig, const char *append); static const char *find_home_for_username (const char *, size_t); +static const char *find_home_for_current_user (void); /* This is called from the script loop if we find a candidate for * ~username (tilde-expansion). @@ -39,13 +40,11 @@ try_tilde_expansion (char *str) { assert (str[0] == '~'); - /* Expand current user's home directory. By simple experimentation - * I found out that bash always uses $HOME. - */ + /* Expand "~" to current user's home directory. */ if (str[1] == '\0') /* ~ */ - return expand_home (NULL); + return expand_home (str, NULL); else if (str[1] == '/') /* ~/... */ - return expand_home (&str[1]); + return expand_home (str, &str[1]); /* Try expanding the part up to the following '\0' or '/' as a * username from the password file. @@ -76,14 +75,21 @@ try_tilde_expansion (char *str) /* Return $HOME + append string. */ static char * -expand_home (const char *append) +expand_home (char *orig, const char *append) { const char *home; int len; char *str; home = getenv ("HOME"); - if (!home) home = "~"; + if (!home) { + /* $HOME not set, bash can look up the current user in the + * password file and find their home that way. (RHBZ#617440). + */ + home = find_home_for_current_user (); + if (!home) + return orig; + } len = strlen (home) + (append ? strlen (append) : 0) + 1; str = malloc (len); @@ -116,3 +122,18 @@ find_home_for_username (const char *username, size_t ulen) return NULL; } + +static const char * +find_home_for_current_user (void) +{ + struct passwd *pw; + uid_t euid = geteuid (); + + setpwent (); + while ((pw = getpwent ()) != NULL) { + if (pw->pw_uid == euid) + return pw->pw_dir; + } + + return NULL; +} |