diff options
Diffstat (limited to 'src/fileio.c')
-rw-r--r-- | src/fileio.c | 36 |
1 files changed, 27 insertions, 9 deletions
diff --git a/src/fileio.c b/src/fileio.c index a1dcb72b4e4..884af25f9fc 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -732,8 +732,8 @@ static unsigned make_temp_name_count, make_temp_name_count_initialized_p; Lisp_Object make_temp_name (Lisp_Object prefix, bool base64_p) { - Lisp_Object val; - int len, clen; + Lisp_Object val, encoded_prefix; + int len; printmax_t pid; char *p, *data; char pidbuf[INT_BUFSIZE_BOUND (printmax_t)]; @@ -767,12 +767,11 @@ make_temp_name (Lisp_Object prefix, bool base64_p) #endif } - len = SBYTES (prefix); clen = SCHARS (prefix); - val = make_uninit_multibyte_string (clen + 3 + pidlen, len + 3 + pidlen); - if (!STRING_MULTIBYTE (prefix)) - STRING_SET_UNIBYTE (val); + encoded_prefix = ENCODE_FILE (prefix); + len = SBYTES (encoded_prefix); + val = make_uninit_string (len + 3 + pidlen); data = SSDATA (val); - memcpy (data, SSDATA (prefix), len); + memcpy (data, SSDATA (encoded_prefix), len); p = data + len; memcpy (p, pidbuf, pidlen); @@ -810,7 +809,7 @@ make_temp_name (Lisp_Object prefix, bool base64_p) { /* We want to return only if errno is ENOENT. */ if (errno == ENOENT) - return val; + return DECODE_FILE (val); else /* The error here is dubious, but there is little else we can do. The alternatives are to return nil, which is @@ -987,7 +986,26 @@ filesystem tree, not (expand-file-name ".." dirname). */) if (multibyte != STRING_MULTIBYTE (default_directory)) { if (multibyte) - default_directory = string_to_multibyte (default_directory); + { + unsigned char *p = SDATA (name); + + while (*p && ASCII_BYTE_P (*p)) + p++; + if (*p == '\0') + { + /* NAME is a pure ASCII string, and DEFAULT_DIRECTORY is + unibyte. Do not convert DEFAULT_DIRECTORY to + multibyte; instead, convert NAME to a unibyte string, + so that the result of this function is also a unibyte + string. This is needed during bootstraping and + dumping, when Emacs cannot decode file names, because + the locale environment is not set up. */ + name = make_unibyte_string (SSDATA (name), SBYTES (name)); + multibyte = 0; + } + else + default_directory = string_to_multibyte (default_directory); + } else { name = string_to_multibyte (name); |