Merge from emacs-24; up to 2012-12-12T22:29:54Z!yamaoka@jpl.org
This commit is contained in:
commit
3f82a88a05
9 changed files with 233 additions and 49 deletions
|
|
@ -1,3 +1,17 @@
|
|||
2013-01-30 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* imenu.el (imenu-default-create-index-function):
|
||||
Put back a version of the infinite loop test removed 2013-01-23.
|
||||
|
||||
2013-01-30 Fabián Ezequiel Gallina <fgallina@cuca>
|
||||
|
||||
* progmodes/python.el (python-shell-parse-command): Find
|
||||
python-shell-interpreter with modified environment.
|
||||
|
||||
2013-01-30 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp/cl.el (cl-set-getf): Add compatibility alias.
|
||||
|
||||
2013-01-29 Alan Mackenzie <acm@muc.de>
|
||||
|
||||
Amend to fontify /regexp/s in actions correctly.
|
||||
|
|
@ -21002,7 +21016,7 @@
|
|||
* nxml/rng-xsd.el (rng-xsd-check-pattern): Use case-sensitive
|
||||
matching (Bug#8516).
|
||||
|
||||
2011-01-22 Jari Aalto <jari.aalto@cante.net>
|
||||
2011-05-22 Jari Aalto <jari.aalto@cante.net>
|
||||
|
||||
* vc/vc-dir.el (vc-default-dir-printer): Give edited tag a
|
||||
different face (Bug#8178).
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
;; Author: David Ponce <david@dponce.com>
|
||||
;; Maintainer: Eric M. Ludlam <zappo@gnu.org>
|
||||
;; Version: 1.0pre7
|
||||
;; Version: 1.1
|
||||
;; Keywords: OO, lisp
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
;;; Copyright (C) 2002-2003, 2005-2013 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Eric M. Ludlam <zappo@gnu.org>
|
||||
;; Version: 0.2
|
||||
;; Version: 1.3
|
||||
;; Keywords: OO, lisp
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
;; Author: Eric M. Ludlam <zappo@gnu.org>
|
||||
;; Keywords: syntax tools
|
||||
;; Version: 2.0
|
||||
;; Version: 2.1beta
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
|
|
|
|||
|
|
@ -689,6 +689,7 @@ You can replace this macro with `gv-letplace'."
|
|||
'cl--map-keymap-recursively "24.3")
|
||||
(define-obsolete-function-alias 'cl-map-intervals 'cl--map-intervals "24.3")
|
||||
(define-obsolete-function-alias 'cl-map-extents 'cl--map-overlays "24.3")
|
||||
(define-obsolete-function-alias 'cl-set-getf 'cl--set-getf "24.3")
|
||||
|
||||
(defun cl-maclisp-member (item list)
|
||||
(declare (obsolete member "24.3"))
|
||||
|
|
|
|||
|
|
@ -678,11 +678,13 @@ The alternate method, which is the one most often used, is to call
|
|||
;; in these major modes. But save that change for later.
|
||||
(cond ((and imenu-prev-index-position-function
|
||||
imenu-extract-index-name-function)
|
||||
(let ((index-alist '()) (pos (point))
|
||||
(let ((index-alist '()) (pos -1)
|
||||
name)
|
||||
(goto-char (point-max))
|
||||
;; Search for the function
|
||||
(while (funcall imenu-prev-index-position-function)
|
||||
(when (= pos (point))
|
||||
(error "Infinite loop at %s:%d: imenu-prev-index-position-function does not move point" (buffer-name) pos))
|
||||
(setq pos (point))
|
||||
(save-excursion
|
||||
(setq name (funcall imenu-extract-index-name-function)))
|
||||
|
|
|
|||
|
|
@ -1664,7 +1664,11 @@ uniqueness for different types of configurations."
|
|||
|
||||
(defun python-shell-parse-command ()
|
||||
"Calculate the string used to execute the inferior Python process."
|
||||
(format "%s %s" python-shell-interpreter python-shell-interpreter-args))
|
||||
(let ((process-environment (python-shell-calculate-process-environment))
|
||||
(exec-path (python-shell-calculate-exec-path)))
|
||||
(format "%s %s"
|
||||
(executable-find python-shell-interpreter)
|
||||
python-shell-interpreter-args)))
|
||||
|
||||
(defun python-shell-calculate-process-environment ()
|
||||
"Calculate process environment given `python-shell-virtualenv-path'."
|
||||
|
|
|
|||
|
|
@ -1,3 +1,19 @@
|
|||
2013-01-30 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32.c (sys_open): Zero out the flags for the new file descriptor.
|
||||
(sys_close): Zero out the flags for the file descriptor before
|
||||
closing it. (Bug#13546)
|
||||
|
||||
* w32.c (parse_root, get_volume_info, readdir, read_unc_volume)
|
||||
(logon_network_drive, stat_worker, symlink, chase_symlinks): Use
|
||||
CharNextExA and CharPrevExA to iterate over file names encoded in
|
||||
DBCS. (Bug#13553)
|
||||
|
||||
* w32.c (w32_get_long_filename, init_environment, readlink):
|
||||
Support file names encoded in DBCS codepages.
|
||||
(readlink): Use the current file-name-coding-system, not the ANSI
|
||||
codepage, to decode and handle targets of symlinks.
|
||||
|
||||
2013-01-28 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* w32.c (opendir): Now accepts a 'const char *'.
|
||||
|
|
|
|||
233
src/w32.c
233
src/w32.c
|
|
@ -37,7 +37,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
/* must include CRT headers *before* config.h */
|
||||
|
||||
#include <config.h>
|
||||
#include <mbstring.h> /* for _mbspbrk and _mbslwr */
|
||||
#include <mbstring.h> /* for _mbspbrk, _mbslwr, _mbsrchr, ... */
|
||||
|
||||
#undef access
|
||||
#undef chdir
|
||||
|
|
@ -1730,12 +1730,17 @@ parse_root (char * name, char ** pPath)
|
|||
else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
|
||||
{
|
||||
int slashes = 2;
|
||||
int dbcs_p = max_filename_mbslen () > 1;
|
||||
|
||||
name += 2;
|
||||
do
|
||||
{
|
||||
if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
|
||||
break;
|
||||
name++;
|
||||
if (dbcs_p)
|
||||
name = CharNextExA (file_name_codepage, name, 0);
|
||||
else
|
||||
name++;
|
||||
}
|
||||
while ( *name );
|
||||
if (IS_DIRECTORY_SEP (name[0]))
|
||||
|
|
@ -1800,7 +1805,7 @@ w32_get_long_filename (char * name, char * buf, int size)
|
|||
while (p != NULL && *p)
|
||||
{
|
||||
q = p;
|
||||
p = strchr (q, '\\');
|
||||
p = _mbschr (q, '\\');
|
||||
if (p) *p = '\0';
|
||||
len = get_long_basename (full, o, size);
|
||||
if (len > 0)
|
||||
|
|
@ -2072,16 +2077,16 @@ init_environment (char ** argv)
|
|||
|
||||
if (!GetModuleFileName (NULL, modname, MAX_PATH))
|
||||
emacs_abort ();
|
||||
if ((p = strrchr (modname, '\\')) == NULL)
|
||||
if ((p = _mbsrchr (modname, '\\')) == NULL)
|
||||
emacs_abort ();
|
||||
*p = 0;
|
||||
|
||||
if ((p = strrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0)
|
||||
if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0)
|
||||
{
|
||||
char buf[SET_ENV_BUF_SIZE];
|
||||
|
||||
*p = 0;
|
||||
for (p = modname; *p; p++)
|
||||
for (p = modname; *p; p = CharNext (p))
|
||||
if (*p == '\\') *p = '/';
|
||||
|
||||
_snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
|
||||
|
|
@ -2096,17 +2101,17 @@ init_environment (char ** argv)
|
|||
|| xstrcasecmp (p, "\\AMD64") == 0))
|
||||
{
|
||||
*p = 0;
|
||||
p = strrchr (modname, '\\');
|
||||
p = _mbsrchr (modname, '\\');
|
||||
if (p != NULL)
|
||||
{
|
||||
*p = 0;
|
||||
p = strrchr (modname, '\\');
|
||||
p = _mbsrchr (modname, '\\');
|
||||
if (p && xstrcasecmp (p, "\\src") == 0)
|
||||
{
|
||||
char buf[SET_ENV_BUF_SIZE];
|
||||
|
||||
*p = 0;
|
||||
for (p = modname; *p; p++)
|
||||
for (p = modname; *p; p = CharNext (p))
|
||||
if (*p == '\\') *p = '/';
|
||||
|
||||
_snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
|
||||
|
|
@ -2641,12 +2646,23 @@ get_volume_info (const char * name, const char ** pPath)
|
|||
{
|
||||
char *str = temp;
|
||||
int slashes = 4;
|
||||
int dbcs_p = max_filename_mbslen () > 1;
|
||||
|
||||
rootname = temp;
|
||||
do
|
||||
{
|
||||
if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
|
||||
break;
|
||||
*str++ = *name++;
|
||||
if (!dbcs_p)
|
||||
*str++ = *name++;
|
||||
else
|
||||
{
|
||||
const char *p = name;
|
||||
|
||||
name = CharNextExA (file_name_codepage, name, 0);
|
||||
memcpy (str, p, name - p);
|
||||
str += name - p;
|
||||
}
|
||||
}
|
||||
while ( *name );
|
||||
|
||||
|
|
@ -2882,11 +2898,23 @@ readdir (DIR *dirp)
|
|||
{
|
||||
char filename[MAXNAMLEN + 3];
|
||||
int ln;
|
||||
int dbcs_p = max_filename_mbslen () > 1;
|
||||
|
||||
strcpy (filename, dir_pathname);
|
||||
ln = strlen (filename) - 1;
|
||||
if (!IS_DIRECTORY_SEP (filename[ln]))
|
||||
strcat (filename, "\\");
|
||||
if (!dbcs_p)
|
||||
{
|
||||
if (!IS_DIRECTORY_SEP (filename[ln]))
|
||||
strcat (filename, "\\");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *end = filename + ln + 1;
|
||||
char *last_char = CharPrevExA (file_name_codepage, filename, end, 0);
|
||||
|
||||
if (!IS_DIRECTORY_SEP (*last_char))
|
||||
strcat (filename, "\\");
|
||||
}
|
||||
strcat (filename, "*");
|
||||
|
||||
/* Note: No need to resolve symlinks in FILENAME, because
|
||||
|
|
@ -2991,6 +3019,7 @@ read_unc_volume (HANDLE henum, char *readbuf, int size)
|
|||
DWORD bufsize = 512;
|
||||
char *buffer;
|
||||
char *ptr;
|
||||
int dbcs_p = max_filename_mbslen () > 1;
|
||||
|
||||
count = 1;
|
||||
buffer = alloca (bufsize);
|
||||
|
|
@ -3001,7 +3030,13 @@ read_unc_volume (HANDLE henum, char *readbuf, int size)
|
|||
/* WNetEnumResource returns \\resource\share...skip forward to "share". */
|
||||
ptr = ((LPNETRESOURCE) buffer)->lpRemoteName;
|
||||
ptr += 2;
|
||||
while (*ptr && !IS_DIRECTORY_SEP (*ptr)) ptr++;
|
||||
if (!dbcs_p)
|
||||
while (*ptr && !IS_DIRECTORY_SEP (*ptr)) ptr++;
|
||||
else
|
||||
{
|
||||
while (*ptr && !IS_DIRECTORY_SEP (*ptr))
|
||||
ptr = CharNextExA (file_name_codepage, ptr, 0);
|
||||
}
|
||||
ptr++;
|
||||
|
||||
strncpy (readbuf, ptr, size);
|
||||
|
|
@ -3038,9 +3073,11 @@ logon_network_drive (const char *path)
|
|||
{
|
||||
NETRESOURCE resource;
|
||||
char share[MAX_PATH];
|
||||
int i, n_slashes;
|
||||
int n_slashes;
|
||||
char drive[4];
|
||||
UINT drvtype;
|
||||
char *p;
|
||||
int dbcs_p;
|
||||
|
||||
if (IS_DIRECTORY_SEP (path[0]) && IS_DIRECTORY_SEP (path[1]))
|
||||
drvtype = DRIVE_REMOTE;
|
||||
|
|
@ -3062,13 +3099,18 @@ logon_network_drive (const char *path)
|
|||
n_slashes = 2;
|
||||
strncpy (share, path, MAX_PATH);
|
||||
/* Truncate to just server and share name. */
|
||||
for (i = 2; i < MAX_PATH; i++)
|
||||
dbcs_p = max_filename_mbslen () > 1;
|
||||
for (p = share + 2; *p && p < share + MAX_PATH; )
|
||||
{
|
||||
if (IS_DIRECTORY_SEP (share[i]) && ++n_slashes > 3)
|
||||
if (IS_DIRECTORY_SEP (*p) && ++n_slashes > 3)
|
||||
{
|
||||
share[i] = '\0';
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
if (dbcs_p)
|
||||
p = CharNextExA (file_name_codepage, p, 0);
|
||||
else
|
||||
p++;
|
||||
}
|
||||
|
||||
resource.dwType = RESOURCETYPE_DISK;
|
||||
|
|
@ -3365,9 +3407,12 @@ sys_open (const char * path, int oflag, int mode)
|
|||
and system files. Force all file handles to be
|
||||
non-inheritable. */
|
||||
int res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
|
||||
if (res >= 0)
|
||||
return res;
|
||||
return _open (mpath, oflag | _O_NOINHERIT, mode);
|
||||
if (res < 0)
|
||||
res = _open (mpath, oflag | _O_NOINHERIT, mode);
|
||||
if (res >= 0 && res < MAXDESC)
|
||||
fd_info[res].flags = 0;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -3843,6 +3888,7 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
|
|||
DWORD access_rights = 0;
|
||||
DWORD fattrs = 0, serialnum = 0, fs_high = 0, fs_low = 0, nlinks = 1;
|
||||
FILETIME ctime, atime, wtime;
|
||||
int dbcs_p;
|
||||
|
||||
if (path == NULL || buf == NULL)
|
||||
{
|
||||
|
|
@ -4040,6 +4086,7 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
|
|||
did not ask for extra precision, resolving symlinks will fly
|
||||
in the face of that request, since the user then wants the
|
||||
lightweight version of the code. */
|
||||
dbcs_p = max_filename_mbslen () > 1;
|
||||
rootdir = (path >= save_name + len - 1
|
||||
&& (IS_DIRECTORY_SEP (*path) || *path == 0));
|
||||
|
||||
|
|
@ -4067,8 +4114,19 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
|
|||
}
|
||||
else if (rootdir)
|
||||
{
|
||||
if (!IS_DIRECTORY_SEP (name[len-1]))
|
||||
strcat (name, "\\");
|
||||
if (!dbcs_p)
|
||||
{
|
||||
if (!IS_DIRECTORY_SEP (name[len-1]))
|
||||
strcat (name, "\\");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *end = name + len;
|
||||
char *n = CharPrevExA (file_name_codepage, name, end, 0);
|
||||
|
||||
if (!IS_DIRECTORY_SEP (*n))
|
||||
strcat (name, "\\");
|
||||
}
|
||||
if (GetDriveType (name) < 2)
|
||||
{
|
||||
errno = ENOENT;
|
||||
|
|
@ -4080,15 +4138,37 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (IS_DIRECTORY_SEP (name[len-1]))
|
||||
name[len - 1] = 0;
|
||||
if (!dbcs_p)
|
||||
{
|
||||
if (IS_DIRECTORY_SEP (name[len-1]))
|
||||
name[len - 1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *end = name + len;
|
||||
char *n = CharPrevExA (file_name_codepage, name, end, 0);
|
||||
|
||||
if (IS_DIRECTORY_SEP (*n))
|
||||
*n = 0;
|
||||
}
|
||||
|
||||
/* (This is hacky, but helps when doing file completions on
|
||||
network drives.) Optimize by using information available from
|
||||
active readdir if possible. */
|
||||
len = strlen (dir_pathname);
|
||||
if (IS_DIRECTORY_SEP (dir_pathname[len-1]))
|
||||
len--;
|
||||
if (!dbcs_p)
|
||||
{
|
||||
if (IS_DIRECTORY_SEP (dir_pathname[len-1]))
|
||||
len--;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *end = dir_pathname + len;
|
||||
char *n = CharPrevExA (file_name_codepage, dir_pathname, end, 0);
|
||||
|
||||
if (IS_DIRECTORY_SEP (*n))
|
||||
len--;
|
||||
}
|
||||
if (dir_find_handle != INVALID_HANDLE_VALUE
|
||||
&& !(is_a_symlink && follow_symlinks)
|
||||
&& strnicmp (save_name, dir_pathname, len) == 0
|
||||
|
|
@ -4359,6 +4439,7 @@ symlink (char const *filename, char const *linkname)
|
|||
char linkfn[MAX_PATH], *tgtfn;
|
||||
DWORD flags = 0;
|
||||
int dir_access, filename_ends_in_slash;
|
||||
int dbcs_p;
|
||||
|
||||
/* Diagnostics follows Posix as much as possible. */
|
||||
if (filename == NULL || linkname == NULL)
|
||||
|
|
@ -4384,6 +4465,8 @@ symlink (char const *filename, char const *linkname)
|
|||
return -1;
|
||||
}
|
||||
|
||||
dbcs_p = max_filename_mbslen () > 1;
|
||||
|
||||
/* Note: since empty FILENAME was already rejected, we can safely
|
||||
refer to FILENAME[1]. */
|
||||
if (!(IS_DIRECTORY_SEP (filename[0]) || IS_DEVICE_SEP (filename[1])))
|
||||
|
|
@ -4398,8 +4481,21 @@ symlink (char const *filename, char const *linkname)
|
|||
char tem[MAX_PATH];
|
||||
char *p = linkfn + strlen (linkfn);
|
||||
|
||||
while (p > linkfn && !IS_ANY_SEP (p[-1]))
|
||||
p--;
|
||||
if (!dbcs_p)
|
||||
{
|
||||
while (p > linkfn && !IS_ANY_SEP (p[-1]))
|
||||
p--;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p1 = CharPrevExA (file_name_codepage, linkfn, p, 0);
|
||||
|
||||
while (p > linkfn && !IS_ANY_SEP (*p1))
|
||||
{
|
||||
p = p1;
|
||||
p1 = CharPrevExA (file_name_codepage, linkfn, p1, 0);
|
||||
}
|
||||
}
|
||||
if (p > linkfn)
|
||||
strncpy (tem, linkfn, p - linkfn);
|
||||
tem[p - linkfn] = '\0';
|
||||
|
|
@ -4414,7 +4510,15 @@ symlink (char const *filename, char const *linkname)
|
|||
exist, but ends in a slash, we create a symlink to directory. If
|
||||
FILENAME exists and is a directory, we always create a symlink to
|
||||
directory. */
|
||||
filename_ends_in_slash = IS_DIRECTORY_SEP (filename[strlen (filename) - 1]);
|
||||
if (!dbcs_p)
|
||||
filename_ends_in_slash = IS_DIRECTORY_SEP (filename[strlen (filename) - 1]);
|
||||
else
|
||||
{
|
||||
const char *end = filename + strlen (filename);
|
||||
const char *n = CharPrevExA (file_name_codepage, filename, end, 0);
|
||||
|
||||
filename_ends_in_slash = IS_DIRECTORY_SEP (*n);
|
||||
}
|
||||
if (dir_access == 0 || filename_ends_in_slash)
|
||||
flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
|
||||
|
||||
|
|
@ -4604,6 +4708,8 @@ readlink (const char *name, char *buf, size_t buf_size)
|
|||
WCHAR *lwname_src =
|
||||
reparse_data->SymbolicLinkReparseBuffer.PathBuffer
|
||||
+ reparse_data->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
|
||||
/* This updates file_name_codepage which we need below. */
|
||||
int dbcs_p = max_filename_mbslen () > 1;
|
||||
|
||||
/* According to MSDN, PrintNameLength does not include the
|
||||
terminating null character. */
|
||||
|
|
@ -4611,9 +4717,7 @@ readlink (const char *name, char *buf, size_t buf_size)
|
|||
memcpy (lwname, lwname_src, lwname_len);
|
||||
lwname[lwname_len/sizeof(WCHAR)] = 0; /* null-terminate */
|
||||
|
||||
/* FIXME: Should we use the current file-name coding system
|
||||
instead of the fixed value of the ANSI codepage? */
|
||||
lname_len = WideCharToMultiByte (w32_ansi_code_page, 0, lwname, -1,
|
||||
lname_len = WideCharToMultiByte (file_name_codepage, 0, lwname, -1,
|
||||
lname, MAX_PATH, NULL, NULL);
|
||||
if (!lname_len)
|
||||
{
|
||||
|
|
@ -4639,18 +4743,33 @@ readlink (const char *name, char *buf, size_t buf_size)
|
|||
else
|
||||
{
|
||||
size_t size_to_copy = buf_size;
|
||||
BYTE *p = lname;
|
||||
BYTE *p = lname, *p2;
|
||||
BYTE *pend = p + lname_len;
|
||||
|
||||
/* Normalize like dostounix_filename does, but we don't
|
||||
want to assume that lname is null-terminated. */
|
||||
if (*p && p[1] == ':' && *p >= 'A' && *p <= 'Z')
|
||||
*p += 'a' - 'A';
|
||||
if (dbcs_p)
|
||||
p2 = CharNextExA (file_name_codepage, p, 0);
|
||||
else
|
||||
p2 = p + 1;
|
||||
if (*p && *p2 == ':' && *p >= 'A' && *p <= 'Z')
|
||||
{
|
||||
*p += 'a' - 'A';
|
||||
p += 2;
|
||||
}
|
||||
while (p <= pend)
|
||||
{
|
||||
if (*p == '\\')
|
||||
*p = '/';
|
||||
++p;
|
||||
if (dbcs_p)
|
||||
{
|
||||
p = CharNextExA (file_name_codepage, p, 0);
|
||||
/* CharNextExA doesn't advance at null character. */
|
||||
if (!*p)
|
||||
break;
|
||||
}
|
||||
else
|
||||
++p;
|
||||
}
|
||||
/* Testing for null-terminated LNAME is paranoia:
|
||||
WideCharToMultiByte should always return a
|
||||
|
|
@ -4724,6 +4843,7 @@ chase_symlinks (const char *file)
|
|||
char link[MAX_PATH];
|
||||
ssize_t res, link_len;
|
||||
int loop_count = 0;
|
||||
int dbcs_p;
|
||||
|
||||
if (is_windows_9x () == TRUE || !is_symlink (file))
|
||||
return (char *)file;
|
||||
|
|
@ -4731,13 +4851,27 @@ chase_symlinks (const char *file)
|
|||
if ((link_len = GetFullPathName (file, MAX_PATH, link, NULL)) == 0)
|
||||
return (char *)file;
|
||||
|
||||
dbcs_p = max_filename_mbslen () > 1;
|
||||
target[0] = '\0';
|
||||
do {
|
||||
|
||||
/* Remove trailing slashes, as we want to resolve the last
|
||||
non-trivial part of the link name. */
|
||||
while (link_len > 3 && IS_DIRECTORY_SEP (link[link_len-1]))
|
||||
link[link_len--] = '\0';
|
||||
if (!dbcs_p)
|
||||
{
|
||||
while (link_len > 3 && IS_DIRECTORY_SEP (link[link_len-1]))
|
||||
link[link_len--] = '\0';
|
||||
}
|
||||
else if (link_len > 3)
|
||||
{
|
||||
char *n = CharPrevExA (file_name_codepage, link, link + link_len, 0);
|
||||
|
||||
while (n >= link + 2 && IS_DIRECTORY_SEP (*n))
|
||||
{
|
||||
n[1] = '\0';
|
||||
n = CharPrevExA (file_name_codepage, link, n, 0);
|
||||
}
|
||||
}
|
||||
|
||||
res = readlink (link, target, MAX_PATH);
|
||||
if (res > 0)
|
||||
|
|
@ -4750,8 +4884,21 @@ chase_symlinks (const char *file)
|
|||
the symlink, then copy the result back to target. */
|
||||
char *p = link + link_len;
|
||||
|
||||
while (p > link && !IS_ANY_SEP (p[-1]))
|
||||
p--;
|
||||
if (!dbcs_p)
|
||||
{
|
||||
while (p > link && !IS_ANY_SEP (p[-1]))
|
||||
p--;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p1 = CharPrevExA (file_name_codepage, link, p, 0);
|
||||
|
||||
while (p > link && !IS_ANY_SEP (*p1))
|
||||
{
|
||||
p = p1;
|
||||
p1 = CharPrevExA (file_name_codepage, link, p1, 0);
|
||||
}
|
||||
}
|
||||
strcpy (p, target);
|
||||
strcpy (target, link);
|
||||
}
|
||||
|
|
@ -6543,15 +6690,15 @@ sys_close (int fd)
|
|||
}
|
||||
}
|
||||
|
||||
if (fd >= 0 && fd < MAXDESC)
|
||||
fd_info[fd].flags = 0;
|
||||
|
||||
/* Note that sockets do not need special treatment here (at least on
|
||||
NT and Windows 95 using the standard tcp/ip stacks) - it appears that
|
||||
closesocket is equivalent to CloseHandle, which is to be expected
|
||||
because socket handles are fully fledged kernel handles. */
|
||||
rc = _close (fd);
|
||||
|
||||
if (rc == 0 && fd < MAXDESC)
|
||||
fd_info[fd].flags = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue