diff options
| author | Paul Eggert | 2018-11-13 09:29:14 -0800 |
|---|---|---|
| committer | Paul Eggert | 2018-11-13 09:32:50 -0800 |
| commit | 900276502fbb4dcabdabc5d7d24b4bc5645f2cf3 (patch) | |
| tree | 4d6c17f5b3cea0f4d5dfbc7243eb6495269a7e56 | |
| parent | ce1fb157e840fd292c3db4632831c4514a663890 (diff) | |
| download | emacs-900276502fbb4dcabdabc5d7d24b4bc5645f2cf3.tar.gz emacs-900276502fbb4dcabdabc5d7d24b4bc5645f2cf3.zip | |
Act like POSIX sh if $HOME is relative
POSIX says sh ~/foo should act like $HOME/foo even if $HOME is
relative, so be consistent with that (Bug#33255).
* admin/merge-gnulib (GNULIB_MODULES): Add dosname.
* src/buffer.c (init_buffer): Use emacs_wd to get
initial working directory with slash appended if needed.
(default-directory): Say it must be absolute.
* src/emacs.c (emacs_wd): New global variable.
(init_cmdargs): Dir arg is now char const *.
(main): Set emacs_wd.
* src/emacs.c (main) [NS_IMPL_COCOA]:
* src/fileio.c (Fexpand_file_name):
Use get_homedir instead of egetenv ("HOME").
* src/fileio.c: Include dosname.h, for IS_ABSOLUTE_FILE_NAME.
(splice_dir_file, get_homedir): New functions.
* src/xrdb.c (gethomedir): Remove. All callers changed
to use get_homedir and splice_dir_file.
* test/src/fileio-tests.el (fileio-tests--relative-HOME): New test.
| -rwxr-xr-x | admin/merge-gnulib | 2 | ||||
| -rw-r--r-- | src/buffer.c | 28 | ||||
| -rw-r--r-- | src/emacs.c | 20 | ||||
| -rw-r--r-- | src/fileio.c | 62 | ||||
| -rw-r--r-- | src/lisp.h | 3 | ||||
| -rw-r--r-- | src/xrdb.c | 54 | ||||
| -rw-r--r-- | test/src/fileio-tests.el | 8 |
7 files changed, 103 insertions, 74 deletions
diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 575e3fa74a7..84dcb0b8752 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib | |||
| @@ -30,7 +30,7 @@ GNULIB_MODULES=' | |||
| 30 | careadlinkat close-stream | 30 | careadlinkat close-stream |
| 31 | count-leading-zeros count-one-bits count-trailing-zeros | 31 | count-leading-zeros count-one-bits count-trailing-zeros |
| 32 | crypto/md5-buffer crypto/sha1-buffer crypto/sha256-buffer crypto/sha512-buffer | 32 | crypto/md5-buffer crypto/sha1-buffer crypto/sha256-buffer crypto/sha512-buffer |
| 33 | d-type diffseq dtoastr dtotimespec dup2 | 33 | d-type diffseq dosname dtoastr dtotimespec dup2 |
| 34 | environ execinfo explicit_bzero faccessat | 34 | environ execinfo explicit_bzero faccessat |
| 35 | fcntl fcntl-h fdatasync fdopendir | 35 | fcntl fcntl-h fdatasync fdopendir |
| 36 | filemode filevercmp flexmember fpieee fstatat fsusage fsync | 36 | filemode filevercmp flexmember fpieee fstatat fsusage fsync |
diff --git a/src/buffer.c b/src/buffer.c index ac2de7d19f2..90ef886b229 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -5268,9 +5268,7 @@ init_buffer_once (void) | |||
| 5268 | void | 5268 | void |
| 5269 | init_buffer (int initialized) | 5269 | init_buffer (int initialized) |
| 5270 | { | 5270 | { |
| 5271 | char *pwd; | ||
| 5272 | Lisp_Object temp; | 5271 | Lisp_Object temp; |
| 5273 | ptrdiff_t len; | ||
| 5274 | 5272 | ||
| 5275 | #ifdef USE_MMAP_FOR_BUFFERS | 5273 | #ifdef USE_MMAP_FOR_BUFFERS |
| 5276 | if (initialized) | 5274 | if (initialized) |
| @@ -5324,7 +5322,7 @@ init_buffer (int initialized) | |||
| 5324 | if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) | 5322 | if (NILP (BVAR (&buffer_defaults, enable_multibyte_characters))) |
| 5325 | Fset_buffer_multibyte (Qnil); | 5323 | Fset_buffer_multibyte (Qnil); |
| 5326 | 5324 | ||
| 5327 | pwd = emacs_get_current_dir_name (); | 5325 | char const *pwd = emacs_wd; |
| 5328 | 5326 | ||
| 5329 | if (!pwd) | 5327 | if (!pwd) |
| 5330 | { | 5328 | { |
| @@ -5336,22 +5334,16 @@ init_buffer (int initialized) | |||
| 5336 | { | 5334 | { |
| 5337 | /* Maybe this should really use some standard subroutine | 5335 | /* Maybe this should really use some standard subroutine |
| 5338 | whose definition is filename syntax dependent. */ | 5336 | whose definition is filename syntax dependent. */ |
| 5339 | len = strlen (pwd); | 5337 | ptrdiff_t len = strlen (pwd); |
| 5340 | if (!(IS_DIRECTORY_SEP (pwd[len - 1]))) | 5338 | bool add_slash = ! IS_DIRECTORY_SEP (pwd[len - 1]); |
| 5341 | { | ||
| 5342 | /* Grow buffer to add directory separator and '\0'. */ | ||
| 5343 | pwd = realloc (pwd, len + 2); | ||
| 5344 | if (!pwd) | ||
| 5345 | fatal ("get_current_dir_name: %s\n", strerror (errno)); | ||
| 5346 | pwd[len] = DIRECTORY_SEP; | ||
| 5347 | pwd[len + 1] = '\0'; | ||
| 5348 | len++; | ||
| 5349 | } | ||
| 5350 | 5339 | ||
| 5351 | /* At this moment, we still don't know how to decode the directory | 5340 | /* At this moment, we still don't know how to decode the directory |
| 5352 | name. So, we keep the bytes in unibyte form so that file I/O | 5341 | name. So, we keep the bytes in unibyte form so that file I/O |
| 5353 | routines correctly get the original bytes. */ | 5342 | routines correctly get the original bytes. */ |
| 5354 | bset_directory (current_buffer, make_unibyte_string (pwd, len)); | 5343 | Lisp_Object dirname = make_unibyte_string (pwd, len + add_slash); |
| 5344 | if (add_slash) | ||
| 5345 | SSET (dirname, len, DIRECTORY_SEP); | ||
| 5346 | bset_directory (current_buffer, dirname); | ||
| 5355 | 5347 | ||
| 5356 | /* Add /: to the front of the name | 5348 | /* Add /: to the front of the name |
| 5357 | if it would otherwise be treated as magic. */ | 5349 | if it would otherwise be treated as magic. */ |
| @@ -5372,8 +5364,6 @@ init_buffer (int initialized) | |||
| 5372 | 5364 | ||
| 5373 | temp = get_minibuffer (0); | 5365 | temp = get_minibuffer (0); |
| 5374 | bset_directory (XBUFFER (temp), BVAR (current_buffer, directory)); | 5366 | bset_directory (XBUFFER (temp), BVAR (current_buffer, directory)); |
| 5375 | |||
| 5376 | free (pwd); | ||
| 5377 | } | 5367 | } |
| 5378 | 5368 | ||
| 5379 | /* Similar to defvar_lisp but define a variable whose value is the | 5369 | /* Similar to defvar_lisp but define a variable whose value is the |
| @@ -5706,8 +5696,8 @@ visual lines rather than logical lines. See the documentation of | |||
| 5706 | DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory), | 5696 | DEFVAR_PER_BUFFER ("default-directory", &BVAR (current_buffer, directory), |
| 5707 | Qstringp, | 5697 | Qstringp, |
| 5708 | doc: /* Name of default directory of current buffer. | 5698 | doc: /* Name of default directory of current buffer. |
| 5709 | It should be a directory name (as opposed to a directory file-name). | 5699 | It should be an absolute directory name; on GNU and Unix systems, |
| 5710 | On GNU and Unix systems, directory names end in a slash `/'. | 5700 | these names start with `/' or `~' and end with `/'. |
| 5711 | To interactively change the default directory, use command `cd'. */); | 5701 | To interactively change the default directory, use command `cd'. */); |
| 5712 | 5702 | ||
| 5713 | DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function), | 5703 | DEFVAR_PER_BUFFER ("auto-fill-function", &BVAR (current_buffer, auto_fill_function), |
diff --git a/src/emacs.c b/src/emacs.c index 512174d562e..acb4959bfea 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -204,6 +204,9 @@ HANDLE w32_daemon_event; | |||
| 204 | char **initial_argv; | 204 | char **initial_argv; |
| 205 | int initial_argc; | 205 | int initial_argc; |
| 206 | 206 | ||
| 207 | /* The name of the working directory, or NULL if this info is unavailable. */ | ||
| 208 | char const *emacs_wd; | ||
| 209 | |||
| 207 | static void sort_args (int argc, char **argv); | 210 | static void sort_args (int argc, char **argv); |
| 208 | static void syms_of_emacs (void); | 211 | static void syms_of_emacs (void); |
| 209 | 212 | ||
| @@ -406,7 +409,7 @@ terminate_due_to_signal (int sig, int backtrace_limit) | |||
| 406 | /* Code for dealing with Lisp access to the Unix command line. */ | 409 | /* Code for dealing with Lisp access to the Unix command line. */ |
| 407 | 410 | ||
| 408 | static void | 411 | static void |
| 409 | init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd) | 412 | init_cmdargs (int argc, char **argv, int skip_args, char const *original_pwd) |
| 410 | { | 413 | { |
| 411 | int i; | 414 | int i; |
| 412 | Lisp_Object name, dir, handler; | 415 | Lisp_Object name, dir, handler; |
| @@ -694,7 +697,7 @@ main (int argc, char **argv) | |||
| 694 | char *ch_to_dir = 0; | 697 | char *ch_to_dir = 0; |
| 695 | 698 | ||
| 696 | /* If we use --chdir, this records the original directory. */ | 699 | /* If we use --chdir, this records the original directory. */ |
| 697 | char *original_pwd = 0; | 700 | char const *original_pwd = 0; |
| 698 | 701 | ||
| 699 | /* Record (approximately) where the stack begins. */ | 702 | /* Record (approximately) where the stack begins. */ |
| 700 | stack_bottom = (char *) &stack_bottom_variable; | 703 | stack_bottom = (char *) &stack_bottom_variable; |
| @@ -794,6 +797,8 @@ main (int argc, char **argv) | |||
| 794 | exit (0); | 797 | exit (0); |
| 795 | } | 798 | } |
| 796 | 799 | ||
| 800 | emacs_wd = emacs_get_current_dir_name (); | ||
| 801 | |||
| 797 | if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args)) | 802 | if (argmatch (argv, argc, "-chdir", "--chdir", 4, &ch_to_dir, &skip_args)) |
| 798 | { | 803 | { |
| 799 | #ifdef WINDOWSNT | 804 | #ifdef WINDOWSNT |
| @@ -804,13 +809,14 @@ main (int argc, char **argv) | |||
| 804 | filename_from_ansi (ch_to_dir, newdir); | 809 | filename_from_ansi (ch_to_dir, newdir); |
| 805 | ch_to_dir = newdir; | 810 | ch_to_dir = newdir; |
| 806 | #endif | 811 | #endif |
| 807 | original_pwd = emacs_get_current_dir_name (); | ||
| 808 | if (chdir (ch_to_dir) != 0) | 812 | if (chdir (ch_to_dir) != 0) |
| 809 | { | 813 | { |
| 810 | fprintf (stderr, "%s: Can't chdir to %s: %s\n", | 814 | fprintf (stderr, "%s: Can't chdir to %s: %s\n", |
| 811 | argv[0], ch_to_dir, strerror (errno)); | 815 | argv[0], ch_to_dir, strerror (errno)); |
| 812 | exit (1); | 816 | exit (1); |
| 813 | } | 817 | } |
| 818 | original_pwd = emacs_wd; | ||
| 819 | emacs_wd = emacs_get_current_dir_name (); | ||
| 814 | } | 820 | } |
| 815 | 821 | ||
| 816 | #if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK) && !defined (CYGWIN) | 822 | #if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK) && !defined (CYGWIN) |
| @@ -1289,21 +1295,21 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem | |||
| 1289 | { | 1295 | { |
| 1290 | #ifdef NS_IMPL_COCOA | 1296 | #ifdef NS_IMPL_COCOA |
| 1291 | /* Started from GUI? */ | 1297 | /* Started from GUI? */ |
| 1292 | /* FIXME: Do the right thing if getenv returns NULL, or if | 1298 | /* FIXME: Do the right thing if get_homedir returns "", or if |
| 1293 | chdir fails. */ | 1299 | chdir fails. */ |
| 1294 | if (! inhibit_window_system && ! isatty (STDIN_FILENO) && ! ch_to_dir) | 1300 | if (! inhibit_window_system && ! isatty (STDIN_FILENO) && ! ch_to_dir) |
| 1295 | chdir (getenv ("HOME")); | 1301 | chdir (get_homedir ()); |
| 1296 | if (skip_args < argc) | 1302 | if (skip_args < argc) |
| 1297 | { | 1303 | { |
| 1298 | if (!strncmp (argv[skip_args], "-psn", 4)) | 1304 | if (!strncmp (argv[skip_args], "-psn", 4)) |
| 1299 | { | 1305 | { |
| 1300 | skip_args += 1; | 1306 | skip_args += 1; |
| 1301 | if (! ch_to_dir) chdir (getenv ("HOME")); | 1307 | if (! ch_to_dir) chdir (get_homedir ()); |
| 1302 | } | 1308 | } |
| 1303 | else if (skip_args+1 < argc && !strncmp (argv[skip_args+1], "-psn", 4)) | 1309 | else if (skip_args+1 < argc && !strncmp (argv[skip_args+1], "-psn", 4)) |
| 1304 | { | 1310 | { |
| 1305 | skip_args += 2; | 1311 | skip_args += 2; |
| 1306 | if (! ch_to_dir) chdir (getenv ("HOME")); | 1312 | if (! ch_to_dir) chdir (get_homedir ()); |
| 1307 | } | 1313 | } |
| 1308 | } | 1314 | } |
| 1309 | #endif /* COCOA */ | 1315 | #endif /* COCOA */ |
diff --git a/src/fileio.c b/src/fileio.c index 7fb865809f5..e178c39fc18 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -96,6 +96,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 96 | #include <acl.h> | 96 | #include <acl.h> |
| 97 | #include <allocator.h> | 97 | #include <allocator.h> |
| 98 | #include <careadlinkat.h> | 98 | #include <careadlinkat.h> |
| 99 | #include <dosname.h> | ||
| 99 | #include <fsusage.h> | 100 | #include <fsusage.h> |
| 100 | #include <stat-time.h> | 101 | #include <stat-time.h> |
| 101 | #include <tempname.h> | 102 | #include <tempname.h> |
| @@ -1093,8 +1094,7 @@ the root directory. */) | |||
| 1093 | { | 1094 | { |
| 1094 | Lisp_Object tem; | 1095 | Lisp_Object tem; |
| 1095 | 1096 | ||
| 1096 | if (!(newdir = egetenv ("HOME"))) | 1097 | newdir = get_homedir (); |
| 1097 | newdir = newdirlim = ""; | ||
| 1098 | nm++; | 1098 | nm++; |
| 1099 | #ifdef WINDOWSNT | 1099 | #ifdef WINDOWSNT |
| 1100 | if (newdir[0]) | 1100 | if (newdir[0]) |
| @@ -1109,7 +1109,7 @@ the root directory. */) | |||
| 1109 | #endif | 1109 | #endif |
| 1110 | tem = build_string (newdir); | 1110 | tem = build_string (newdir); |
| 1111 | newdirlim = newdir + SBYTES (tem); | 1111 | newdirlim = newdir + SBYTES (tem); |
| 1112 | /* `egetenv' may return a unibyte string, which will bite us | 1112 | /* get_homedir may return a unibyte string, which will bite us |
| 1113 | if we expect the directory to be multibyte. */ | 1113 | if we expect the directory to be multibyte. */ |
| 1114 | if (multibyte && !STRING_MULTIBYTE (tem)) | 1114 | if (multibyte && !STRING_MULTIBYTE (tem)) |
| 1115 | { | 1115 | { |
| @@ -1637,7 +1637,6 @@ See also the function `substitute-in-file-name'.") | |||
| 1637 | } | 1637 | } |
| 1638 | #endif | 1638 | #endif |
| 1639 | 1639 | ||
| 1640 | /* If /~ or // appears, discard everything through first slash. */ | ||
| 1641 | static bool | 1640 | static bool |
| 1642 | file_name_absolute_p (const char *filename) | 1641 | file_name_absolute_p (const char *filename) |
| 1643 | { | 1642 | { |
| @@ -1650,6 +1649,61 @@ file_name_absolute_p (const char *filename) | |||
| 1650 | ); | 1649 | ); |
| 1651 | } | 1650 | } |
| 1652 | 1651 | ||
| 1652 | /* Put into BUF the concatenation of DIR and FILE, with an intervening | ||
| 1653 | directory separator if needed. Return a pointer to the null byte | ||
| 1654 | at the end of the concatenated string. */ | ||
| 1655 | char * | ||
| 1656 | splice_dir_file (char *buf, char const *dir, char const *file) | ||
| 1657 | { | ||
| 1658 | char *e = stpcpy (buf, dir); | ||
| 1659 | *e = DIRECTORY_SEP; | ||
| 1660 | e += ! (buf < e && IS_DIRECTORY_SEP (e[-1])); | ||
| 1661 | return stpcpy (e, file); | ||
| 1662 | } | ||
| 1663 | |||
| 1664 | /* Get the home directory, an absolute file name. Return the empty | ||
| 1665 | string on failure. The returned value does not survive garbage | ||
| 1666 | collection, calls to this function, or calls to the getpwnam class | ||
| 1667 | of functions. */ | ||
| 1668 | char const * | ||
| 1669 | get_homedir (void) | ||
| 1670 | { | ||
| 1671 | char const *home = egetenv ("HOME"); | ||
| 1672 | if (!home) | ||
| 1673 | { | ||
| 1674 | static char const *userenv[] = {"LOGNAME", "USER"}; | ||
| 1675 | struct passwd *pw = NULL; | ||
| 1676 | for (int i = 0; i < ARRAYELTS (userenv); i++) | ||
| 1677 | { | ||
| 1678 | char *user = egetenv (userenv[i]); | ||
| 1679 | if (user) | ||
| 1680 | { | ||
| 1681 | pw = getpwnam (user); | ||
| 1682 | if (pw) | ||
| 1683 | break; | ||
| 1684 | } | ||
| 1685 | } | ||
| 1686 | if (!pw) | ||
| 1687 | pw = getpwuid (getuid ()); | ||
| 1688 | if (pw) | ||
| 1689 | home = pw->pw_dir; | ||
| 1690 | if (!home) | ||
| 1691 | return ""; | ||
| 1692 | } | ||
| 1693 | if (IS_ABSOLUTE_FILE_NAME (home)) | ||
| 1694 | return home; | ||
| 1695 | if (!emacs_wd) | ||
| 1696 | error ("$HOME is relative to unknown directory"); | ||
| 1697 | static char *ahome; | ||
| 1698 | static ptrdiff_t ahomesize; | ||
| 1699 | ptrdiff_t ahomelenbound = strlen (emacs_wd) + 1 + strlen (home) + 1; | ||
| 1700 | if (ahomesize <= ahomelenbound) | ||
| 1701 | ahome = xpalloc (ahome, &ahomesize, ahomelenbound + 1 - ahomesize, -1, 1); | ||
| 1702 | splice_dir_file (ahome, emacs_wd, home); | ||
| 1703 | return ahome; | ||
| 1704 | } | ||
| 1705 | |||
| 1706 | /* If /~ or // appears, discard everything through first slash. */ | ||
| 1653 | static char * | 1707 | static char * |
| 1654 | search_embedded_absfilename (char *nm, char *endp) | 1708 | search_embedded_absfilename (char *nm, char *endp) |
| 1655 | { | 1709 | { |
diff --git a/src/lisp.h b/src/lisp.h index f8ffb33a641..7e7dba631f3 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4061,6 +4061,8 @@ extern void syms_of_marker (void); | |||
| 4061 | 4061 | ||
| 4062 | /* Defined in fileio.c. */ | 4062 | /* Defined in fileio.c. */ |
| 4063 | 4063 | ||
| 4064 | extern char *splice_dir_file (char *, char const *, char const *); | ||
| 4065 | extern char const *get_homedir (void); | ||
| 4064 | extern Lisp_Object expand_and_dir_to_file (Lisp_Object); | 4066 | extern Lisp_Object expand_and_dir_to_file (Lisp_Object); |
| 4065 | extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object, | 4067 | extern Lisp_Object write_region (Lisp_Object, Lisp_Object, Lisp_Object, |
| 4066 | Lisp_Object, Lisp_Object, Lisp_Object, | 4068 | Lisp_Object, Lisp_Object, Lisp_Object, |
| @@ -4185,6 +4187,7 @@ extern void syms_of_frame (void); | |||
| 4185 | /* Defined in emacs.c. */ | 4187 | /* Defined in emacs.c. */ |
| 4186 | extern char **initial_argv; | 4188 | extern char **initial_argv; |
| 4187 | extern int initial_argc; | 4189 | extern int initial_argc; |
| 4190 | extern char const *emacs_wd; | ||
| 4188 | #if defined (HAVE_X_WINDOWS) || defined (HAVE_NS) | 4191 | #if defined (HAVE_X_WINDOWS) || defined (HAVE_NS) |
| 4189 | extern bool display_arg; | 4192 | extern bool display_arg; |
| 4190 | #endif | 4193 | #endif |
diff --git a/src/xrdb.c b/src/xrdb.c index 4abf1ad84ed..87c2faf6598 100644 --- a/src/xrdb.c +++ b/src/xrdb.c | |||
| @@ -202,35 +202,6 @@ magic_db (const char *string, ptrdiff_t string_len, const char *class, | |||
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | 204 | ||
| 205 | static char * | ||
| 206 | gethomedir (void) | ||
| 207 | { | ||
| 208 | struct passwd *pw; | ||
| 209 | char *ptr; | ||
| 210 | char *copy; | ||
| 211 | |||
| 212 | if ((ptr = getenv ("HOME")) == NULL) | ||
| 213 | { | ||
| 214 | if ((ptr = getenv ("LOGNAME")) != NULL | ||
| 215 | || (ptr = getenv ("USER")) != NULL) | ||
| 216 | pw = getpwnam (ptr); | ||
| 217 | else | ||
| 218 | pw = getpwuid (getuid ()); | ||
| 219 | |||
| 220 | if (pw) | ||
| 221 | ptr = pw->pw_dir; | ||
| 222 | } | ||
| 223 | |||
| 224 | if (ptr == NULL) | ||
| 225 | return xstrdup ("/"); | ||
| 226 | |||
| 227 | ptrdiff_t len = strlen (ptr); | ||
| 228 | copy = xmalloc (len + 2); | ||
| 229 | strcpy (copy + len, "/"); | ||
| 230 | return memcpy (copy, ptr, len); | ||
| 231 | } | ||
| 232 | |||
| 233 | |||
| 234 | /* Find the first element of SEARCH_PATH which exists and is readable, | 205 | /* Find the first element of SEARCH_PATH which exists and is readable, |
| 235 | after expanding the %-escapes. Return 0 if we didn't find any, and | 206 | after expanding the %-escapes. Return 0 if we didn't find any, and |
| 236 | the path name of the one we found otherwise. */ | 207 | the path name of the one we found otherwise. */ |
| @@ -316,12 +287,11 @@ get_user_app (const char *class) | |||
| 316 | if (! db) | 287 | if (! db) |
| 317 | { | 288 | { |
| 318 | /* Check in the home directory. This is a bit of a hack; let's | 289 | /* Check in the home directory. This is a bit of a hack; let's |
| 319 | hope one's home directory doesn't contain any %-escapes. */ | 290 | hope one's home directory doesn't contain ':' or '%'. */ |
| 320 | char *home = gethomedir (); | 291 | char const *home = get_homedir (); |
| 321 | db = search_magic_path (home, class, "%L/%N"); | 292 | db = search_magic_path (home, class, "%L/%N"); |
| 322 | if (! db) | 293 | if (! db) |
| 323 | db = search_magic_path (home, class, "%N"); | 294 | db = search_magic_path (home, class, "%N"); |
| 324 | xfree (home); | ||
| 325 | } | 295 | } |
| 326 | 296 | ||
| 327 | return db; | 297 | return db; |
| @@ -346,10 +316,9 @@ get_user_db (Display *display) | |||
| 346 | else | 316 | else |
| 347 | { | 317 | { |
| 348 | /* Use ~/.Xdefaults. */ | 318 | /* Use ~/.Xdefaults. */ |
| 349 | char *home = gethomedir (); | 319 | char const *home = get_homedir (); |
| 350 | ptrdiff_t homelen = strlen (home); | 320 | char *filename = xmalloc (strlen (home) + 1 + sizeof xdefaults); |
| 351 | char *filename = xrealloc (home, homelen + sizeof xdefaults); | 321 | splice_dir_file (filename, home, xdefaults); |
| 352 | strcpy (filename + homelen, xdefaults); | ||
| 353 | db = XrmGetFileDatabase (filename); | 322 | db = XrmGetFileDatabase (filename); |
| 354 | xfree (filename); | 323 | xfree (filename); |
| 355 | } | 324 | } |
| @@ -380,13 +349,12 @@ get_environ_db (void) | |||
| 380 | if (STRINGP (system_name)) | 349 | if (STRINGP (system_name)) |
| 381 | { | 350 | { |
| 382 | /* Use ~/.Xdefaults-HOSTNAME. */ | 351 | /* Use ~/.Xdefaults-HOSTNAME. */ |
| 383 | char *home = gethomedir (); | 352 | char const *home = get_homedir (); |
| 384 | ptrdiff_t homelen = strlen (home); | 353 | p = filename = xmalloc (strlen (home) + 1 + sizeof xdefaults |
| 385 | ptrdiff_t filenamesize = (homelen + sizeof xdefaults | 354 | + 1 + SBYTES (system_name)); |
| 386 | + 1 + SBYTES (system_name)); | 355 | char *e = splice_dir_file (p, home, xdefaults); |
| 387 | p = filename = xrealloc (home, filenamesize); | 356 | *e++ = '/'; |
| 388 | lispstpcpy (stpcpy (stpcpy (filename + homelen, xdefaults), "-"), | 357 | lispstpcpy (e, system_name); |
| 389 | system_name); | ||
| 390 | } | 358 | } |
| 391 | } | 359 | } |
| 392 | 360 | ||
diff --git a/test/src/fileio-tests.el b/test/src/fileio-tests.el index 5d12685fa19..b7b78bbda09 100644 --- a/test/src/fileio-tests.el +++ b/test/src/fileio-tests.el | |||
| @@ -95,3 +95,11 @@ Also check that an encoding error can appear in a symlink." | |||
| 95 | (should (equal (file-name-as-directory "d:/abc/") "d:/abc/")) | 95 | (should (equal (file-name-as-directory "d:/abc/") "d:/abc/")) |
| 96 | (should (equal (file-name-as-directory "D:\\abc/") "d:/abc/")) | 96 | (should (equal (file-name-as-directory "D:\\abc/") "d:/abc/")) |
| 97 | (should (equal (file-name-as-directory "D:/abc//") "d:/abc//"))) | 97 | (should (equal (file-name-as-directory "D:/abc//") "d:/abc//"))) |
| 98 | |||
| 99 | (ert-deftest fileio-tests--relative-HOME () | ||
| 100 | "Test that expand-file-name works even when HOME is relative." | ||
| 101 | (let ((old-home (getenv "HOME"))) | ||
| 102 | (setenv "HOME" "a/b/c") | ||
| 103 | (should (equal (expand-file-name "~/foo") | ||
| 104 | (expand-file-name "a/b/c/foo"))) | ||
| 105 | (setenv "HOME" old-home))) | ||