aboutsummaryrefslogtreecommitdiffstats
path: root/src/w32.c
diff options
context:
space:
mode:
authorJoakim Verona2013-01-31 00:03:36 +0100
committerJoakim Verona2013-01-31 00:03:36 +0100
commit9658cee25c3e3f97d02f4fa05f9ee4f2f14fd76b (patch)
tree559caa9a4504175eb0d230f16c08251d56504072 /src/w32.c
parentde18b41154d227d8c7de62647008b73ca3a594c1 (diff)
parent5f9eccc4b6eb6d6a5fcf16b9ec3ee4d331c468cb (diff)
downloademacs-9658cee25c3e3f97d02f4fa05f9ee4f2f14fd76b.tar.gz
emacs-9658cee25c3e3f97d02f4fa05f9ee4f2f14fd76b.zip
auto upstream
Diffstat (limited to 'src/w32.c')
-rw-r--r--src/w32.c233
1 files changed, 190 insertions, 43 deletions
diff --git a/src/w32.c b/src/w32.c
index 6bcc8e19278..d0af53889e7 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -37,7 +37,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
37/* must include CRT headers *before* config.h */ 37/* must include CRT headers *before* config.h */
38 38
39#include <config.h> 39#include <config.h>
40#include <mbstring.h> /* for _mbspbrk and _mbslwr */ 40#include <mbstring.h> /* for _mbspbrk, _mbslwr, _mbsrchr, ... */
41 41
42#undef access 42#undef access
43#undef chdir 43#undef chdir
@@ -1730,12 +1730,17 @@ parse_root (char * name, char ** pPath)
1730 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1])) 1730 else if (IS_DIRECTORY_SEP (name[0]) && IS_DIRECTORY_SEP (name[1]))
1731 { 1731 {
1732 int slashes = 2; 1732 int slashes = 2;
1733 int dbcs_p = max_filename_mbslen () > 1;
1734
1733 name += 2; 1735 name += 2;
1734 do 1736 do
1735 { 1737 {
1736 if (IS_DIRECTORY_SEP (*name) && --slashes == 0) 1738 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
1737 break; 1739 break;
1738 name++; 1740 if (dbcs_p)
1741 name = CharNextExA (file_name_codepage, name, 0);
1742 else
1743 name++;
1739 } 1744 }
1740 while ( *name ); 1745 while ( *name );
1741 if (IS_DIRECTORY_SEP (name[0])) 1746 if (IS_DIRECTORY_SEP (name[0]))
@@ -1800,7 +1805,7 @@ w32_get_long_filename (char * name, char * buf, int size)
1800 while (p != NULL && *p) 1805 while (p != NULL && *p)
1801 { 1806 {
1802 q = p; 1807 q = p;
1803 p = strchr (q, '\\'); 1808 p = _mbschr (q, '\\');
1804 if (p) *p = '\0'; 1809 if (p) *p = '\0';
1805 len = get_long_basename (full, o, size); 1810 len = get_long_basename (full, o, size);
1806 if (len > 0) 1811 if (len > 0)
@@ -2072,16 +2077,16 @@ init_environment (char ** argv)
2072 2077
2073 if (!GetModuleFileName (NULL, modname, MAX_PATH)) 2078 if (!GetModuleFileName (NULL, modname, MAX_PATH))
2074 emacs_abort (); 2079 emacs_abort ();
2075 if ((p = strrchr (modname, '\\')) == NULL) 2080 if ((p = _mbsrchr (modname, '\\')) == NULL)
2076 emacs_abort (); 2081 emacs_abort ();
2077 *p = 0; 2082 *p = 0;
2078 2083
2079 if ((p = strrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0) 2084 if ((p = _mbsrchr (modname, '\\')) && xstrcasecmp (p, "\\bin") == 0)
2080 { 2085 {
2081 char buf[SET_ENV_BUF_SIZE]; 2086 char buf[SET_ENV_BUF_SIZE];
2082 2087
2083 *p = 0; 2088 *p = 0;
2084 for (p = modname; *p; p++) 2089 for (p = modname; *p; p = CharNext (p))
2085 if (*p == '\\') *p = '/'; 2090 if (*p == '\\') *p = '/';
2086 2091
2087 _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); 2092 _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
@@ -2096,17 +2101,17 @@ init_environment (char ** argv)
2096 || xstrcasecmp (p, "\\AMD64") == 0)) 2101 || xstrcasecmp (p, "\\AMD64") == 0))
2097 { 2102 {
2098 *p = 0; 2103 *p = 0;
2099 p = strrchr (modname, '\\'); 2104 p = _mbsrchr (modname, '\\');
2100 if (p != NULL) 2105 if (p != NULL)
2101 { 2106 {
2102 *p = 0; 2107 *p = 0;
2103 p = strrchr (modname, '\\'); 2108 p = _mbsrchr (modname, '\\');
2104 if (p && xstrcasecmp (p, "\\src") == 0) 2109 if (p && xstrcasecmp (p, "\\src") == 0)
2105 { 2110 {
2106 char buf[SET_ENV_BUF_SIZE]; 2111 char buf[SET_ENV_BUF_SIZE];
2107 2112
2108 *p = 0; 2113 *p = 0;
2109 for (p = modname; *p; p++) 2114 for (p = modname; *p; p = CharNext (p))
2110 if (*p == '\\') *p = '/'; 2115 if (*p == '\\') *p = '/';
2111 2116
2112 _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname); 2117 _snprintf (buf, sizeof (buf)-1, "emacs_dir=%s", modname);
@@ -2641,12 +2646,23 @@ get_volume_info (const char * name, const char ** pPath)
2641 { 2646 {
2642 char *str = temp; 2647 char *str = temp;
2643 int slashes = 4; 2648 int slashes = 4;
2649 int dbcs_p = max_filename_mbslen () > 1;
2650
2644 rootname = temp; 2651 rootname = temp;
2645 do 2652 do
2646 { 2653 {
2647 if (IS_DIRECTORY_SEP (*name) && --slashes == 0) 2654 if (IS_DIRECTORY_SEP (*name) && --slashes == 0)
2648 break; 2655 break;
2649 *str++ = *name++; 2656 if (!dbcs_p)
2657 *str++ = *name++;
2658 else
2659 {
2660 const char *p = name;
2661
2662 name = CharNextExA (file_name_codepage, name, 0);
2663 memcpy (str, p, name - p);
2664 str += name - p;
2665 }
2650 } 2666 }
2651 while ( *name ); 2667 while ( *name );
2652 2668
@@ -2882,11 +2898,23 @@ readdir (DIR *dirp)
2882 { 2898 {
2883 char filename[MAXNAMLEN + 3]; 2899 char filename[MAXNAMLEN + 3];
2884 int ln; 2900 int ln;
2901 int dbcs_p = max_filename_mbslen () > 1;
2885 2902
2886 strcpy (filename, dir_pathname); 2903 strcpy (filename, dir_pathname);
2887 ln = strlen (filename) - 1; 2904 ln = strlen (filename) - 1;
2888 if (!IS_DIRECTORY_SEP (filename[ln])) 2905 if (!dbcs_p)
2889 strcat (filename, "\\"); 2906 {
2907 if (!IS_DIRECTORY_SEP (filename[ln]))
2908 strcat (filename, "\\");
2909 }
2910 else
2911 {
2912 char *end = filename + ln + 1;
2913 char *last_char = CharPrevExA (file_name_codepage, filename, end, 0);
2914
2915 if (!IS_DIRECTORY_SEP (*last_char))
2916 strcat (filename, "\\");
2917 }
2890 strcat (filename, "*"); 2918 strcat (filename, "*");
2891 2919
2892 /* Note: No need to resolve symlinks in FILENAME, because 2920 /* Note: No need to resolve symlinks in FILENAME, because
@@ -2991,6 +3019,7 @@ read_unc_volume (HANDLE henum, char *readbuf, int size)
2991 DWORD bufsize = 512; 3019 DWORD bufsize = 512;
2992 char *buffer; 3020 char *buffer;
2993 char *ptr; 3021 char *ptr;
3022 int dbcs_p = max_filename_mbslen () > 1;
2994 3023
2995 count = 1; 3024 count = 1;
2996 buffer = alloca (bufsize); 3025 buffer = alloca (bufsize);
@@ -3001,7 +3030,13 @@ read_unc_volume (HANDLE henum, char *readbuf, int size)
3001 /* WNetEnumResource returns \\resource\share...skip forward to "share". */ 3030 /* WNetEnumResource returns \\resource\share...skip forward to "share". */
3002 ptr = ((LPNETRESOURCE) buffer)->lpRemoteName; 3031 ptr = ((LPNETRESOURCE) buffer)->lpRemoteName;
3003 ptr += 2; 3032 ptr += 2;
3004 while (*ptr && !IS_DIRECTORY_SEP (*ptr)) ptr++; 3033 if (!dbcs_p)
3034 while (*ptr && !IS_DIRECTORY_SEP (*ptr)) ptr++;
3035 else
3036 {
3037 while (*ptr && !IS_DIRECTORY_SEP (*ptr))
3038 ptr = CharNextExA (file_name_codepage, ptr, 0);
3039 }
3005 ptr++; 3040 ptr++;
3006 3041
3007 strncpy (readbuf, ptr, size); 3042 strncpy (readbuf, ptr, size);
@@ -3038,9 +3073,11 @@ logon_network_drive (const char *path)
3038{ 3073{
3039 NETRESOURCE resource; 3074 NETRESOURCE resource;
3040 char share[MAX_PATH]; 3075 char share[MAX_PATH];
3041 int i, n_slashes; 3076 int n_slashes;
3042 char drive[4]; 3077 char drive[4];
3043 UINT drvtype; 3078 UINT drvtype;
3079 char *p;
3080 int dbcs_p;
3044 3081
3045 if (IS_DIRECTORY_SEP (path[0]) && IS_DIRECTORY_SEP (path[1])) 3082 if (IS_DIRECTORY_SEP (path[0]) && IS_DIRECTORY_SEP (path[1]))
3046 drvtype = DRIVE_REMOTE; 3083 drvtype = DRIVE_REMOTE;
@@ -3062,13 +3099,18 @@ logon_network_drive (const char *path)
3062 n_slashes = 2; 3099 n_slashes = 2;
3063 strncpy (share, path, MAX_PATH); 3100 strncpy (share, path, MAX_PATH);
3064 /* Truncate to just server and share name. */ 3101 /* Truncate to just server and share name. */
3065 for (i = 2; i < MAX_PATH; i++) 3102 dbcs_p = max_filename_mbslen () > 1;
3103 for (p = share + 2; *p && p < share + MAX_PATH; )
3066 { 3104 {
3067 if (IS_DIRECTORY_SEP (share[i]) && ++n_slashes > 3) 3105 if (IS_DIRECTORY_SEP (*p) && ++n_slashes > 3)
3068 { 3106 {
3069 share[i] = '\0'; 3107 *p = '\0';
3070 break; 3108 break;
3071 } 3109 }
3110 if (dbcs_p)
3111 p = CharNextExA (file_name_codepage, p, 0);
3112 else
3113 p++;
3072 } 3114 }
3073 3115
3074 resource.dwType = RESOURCETYPE_DISK; 3116 resource.dwType = RESOURCETYPE_DISK;
@@ -3365,9 +3407,12 @@ sys_open (const char * path, int oflag, int mode)
3365 and system files. Force all file handles to be 3407 and system files. Force all file handles to be
3366 non-inheritable. */ 3408 non-inheritable. */
3367 int res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode); 3409 int res = _open (mpath, (oflag & ~_O_CREAT) | _O_NOINHERIT, mode);
3368 if (res >= 0) 3410 if (res < 0)
3369 return res; 3411 res = _open (mpath, oflag | _O_NOINHERIT, mode);
3370 return _open (mpath, oflag | _O_NOINHERIT, mode); 3412 if (res >= 0 && res < MAXDESC)
3413 fd_info[res].flags = 0;
3414
3415 return res;
3371} 3416}
3372 3417
3373int 3418int
@@ -3843,6 +3888,7 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
3843 DWORD access_rights = 0; 3888 DWORD access_rights = 0;
3844 DWORD fattrs = 0, serialnum = 0, fs_high = 0, fs_low = 0, nlinks = 1; 3889 DWORD fattrs = 0, serialnum = 0, fs_high = 0, fs_low = 0, nlinks = 1;
3845 FILETIME ctime, atime, wtime; 3890 FILETIME ctime, atime, wtime;
3891 int dbcs_p;
3846 3892
3847 if (path == NULL || buf == NULL) 3893 if (path == NULL || buf == NULL)
3848 { 3894 {
@@ -4040,6 +4086,7 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
4040 did not ask for extra precision, resolving symlinks will fly 4086 did not ask for extra precision, resolving symlinks will fly
4041 in the face of that request, since the user then wants the 4087 in the face of that request, since the user then wants the
4042 lightweight version of the code. */ 4088 lightweight version of the code. */
4089 dbcs_p = max_filename_mbslen () > 1;
4043 rootdir = (path >= save_name + len - 1 4090 rootdir = (path >= save_name + len - 1
4044 && (IS_DIRECTORY_SEP (*path) || *path == 0)); 4091 && (IS_DIRECTORY_SEP (*path) || *path == 0));
4045 4092
@@ -4067,8 +4114,19 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
4067 } 4114 }
4068 else if (rootdir) 4115 else if (rootdir)
4069 { 4116 {
4070 if (!IS_DIRECTORY_SEP (name[len-1])) 4117 if (!dbcs_p)
4071 strcat (name, "\\"); 4118 {
4119 if (!IS_DIRECTORY_SEP (name[len-1]))
4120 strcat (name, "\\");
4121 }
4122 else
4123 {
4124 char *end = name + len;
4125 char *n = CharPrevExA (file_name_codepage, name, end, 0);
4126
4127 if (!IS_DIRECTORY_SEP (*n))
4128 strcat (name, "\\");
4129 }
4072 if (GetDriveType (name) < 2) 4130 if (GetDriveType (name) < 2)
4073 { 4131 {
4074 errno = ENOENT; 4132 errno = ENOENT;
@@ -4080,15 +4138,37 @@ stat_worker (const char * path, struct stat * buf, int follow_symlinks)
4080 } 4138 }
4081 else 4139 else
4082 { 4140 {
4083 if (IS_DIRECTORY_SEP (name[len-1])) 4141 if (!dbcs_p)
4084 name[len - 1] = 0; 4142 {
4143 if (IS_DIRECTORY_SEP (name[len-1]))
4144 name[len - 1] = 0;
4145 }
4146 else
4147 {
4148 char *end = name + len;
4149 char *n = CharPrevExA (file_name_codepage, name, end, 0);
4150
4151 if (IS_DIRECTORY_SEP (*n))
4152 *n = 0;
4153 }
4085 4154
4086 /* (This is hacky, but helps when doing file completions on 4155 /* (This is hacky, but helps when doing file completions on
4087 network drives.) Optimize by using information available from 4156 network drives.) Optimize by using information available from
4088 active readdir if possible. */ 4157 active readdir if possible. */
4089 len = strlen (dir_pathname); 4158 len = strlen (dir_pathname);
4090 if (IS_DIRECTORY_SEP (dir_pathname[len-1])) 4159 if (!dbcs_p)
4091 len--; 4160 {
4161 if (IS_DIRECTORY_SEP (dir_pathname[len-1]))
4162 len--;
4163 }
4164 else
4165 {
4166 char *end = dir_pathname + len;
4167 char *n = CharPrevExA (file_name_codepage, dir_pathname, end, 0);
4168
4169 if (IS_DIRECTORY_SEP (*n))
4170 len--;
4171 }
4092 if (dir_find_handle != INVALID_HANDLE_VALUE 4172 if (dir_find_handle != INVALID_HANDLE_VALUE
4093 && !(is_a_symlink && follow_symlinks) 4173 && !(is_a_symlink && follow_symlinks)
4094 && strnicmp (save_name, dir_pathname, len) == 0 4174 && strnicmp (save_name, dir_pathname, len) == 0
@@ -4359,6 +4439,7 @@ symlink (char const *filename, char const *linkname)
4359 char linkfn[MAX_PATH], *tgtfn; 4439 char linkfn[MAX_PATH], *tgtfn;
4360 DWORD flags = 0; 4440 DWORD flags = 0;
4361 int dir_access, filename_ends_in_slash; 4441 int dir_access, filename_ends_in_slash;
4442 int dbcs_p;
4362 4443
4363 /* Diagnostics follows Posix as much as possible. */ 4444 /* Diagnostics follows Posix as much as possible. */
4364 if (filename == NULL || linkname == NULL) 4445 if (filename == NULL || linkname == NULL)
@@ -4384,6 +4465,8 @@ symlink (char const *filename, char const *linkname)
4384 return -1; 4465 return -1;
4385 } 4466 }
4386 4467
4468 dbcs_p = max_filename_mbslen () > 1;
4469
4387 /* Note: since empty FILENAME was already rejected, we can safely 4470 /* Note: since empty FILENAME was already rejected, we can safely
4388 refer to FILENAME[1]. */ 4471 refer to FILENAME[1]. */
4389 if (!(IS_DIRECTORY_SEP (filename[0]) || IS_DEVICE_SEP (filename[1]))) 4472 if (!(IS_DIRECTORY_SEP (filename[0]) || IS_DEVICE_SEP (filename[1])))
@@ -4398,8 +4481,21 @@ symlink (char const *filename, char const *linkname)
4398 char tem[MAX_PATH]; 4481 char tem[MAX_PATH];
4399 char *p = linkfn + strlen (linkfn); 4482 char *p = linkfn + strlen (linkfn);
4400 4483
4401 while (p > linkfn && !IS_ANY_SEP (p[-1])) 4484 if (!dbcs_p)
4402 p--; 4485 {
4486 while (p > linkfn && !IS_ANY_SEP (p[-1]))
4487 p--;
4488 }
4489 else
4490 {
4491 char *p1 = CharPrevExA (file_name_codepage, linkfn, p, 0);
4492
4493 while (p > linkfn && !IS_ANY_SEP (*p1))
4494 {
4495 p = p1;
4496 p1 = CharPrevExA (file_name_codepage, linkfn, p1, 0);
4497 }
4498 }
4403 if (p > linkfn) 4499 if (p > linkfn)
4404 strncpy (tem, linkfn, p - linkfn); 4500 strncpy (tem, linkfn, p - linkfn);
4405 tem[p - linkfn] = '\0'; 4501 tem[p - linkfn] = '\0';
@@ -4414,7 +4510,15 @@ symlink (char const *filename, char const *linkname)
4414 exist, but ends in a slash, we create a symlink to directory. If 4510 exist, but ends in a slash, we create a symlink to directory. If
4415 FILENAME exists and is a directory, we always create a symlink to 4511 FILENAME exists and is a directory, we always create a symlink to
4416 directory. */ 4512 directory. */
4417 filename_ends_in_slash = IS_DIRECTORY_SEP (filename[strlen (filename) - 1]); 4513 if (!dbcs_p)
4514 filename_ends_in_slash = IS_DIRECTORY_SEP (filename[strlen (filename) - 1]);
4515 else
4516 {
4517 const char *end = filename + strlen (filename);
4518 const char *n = CharPrevExA (file_name_codepage, filename, end, 0);
4519
4520 filename_ends_in_slash = IS_DIRECTORY_SEP (*n);
4521 }
4418 if (dir_access == 0 || filename_ends_in_slash) 4522 if (dir_access == 0 || filename_ends_in_slash)
4419 flags = SYMBOLIC_LINK_FLAG_DIRECTORY; 4523 flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
4420 4524
@@ -4604,6 +4708,8 @@ readlink (const char *name, char *buf, size_t buf_size)
4604 WCHAR *lwname_src = 4708 WCHAR *lwname_src =
4605 reparse_data->SymbolicLinkReparseBuffer.PathBuffer 4709 reparse_data->SymbolicLinkReparseBuffer.PathBuffer
4606 + reparse_data->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR); 4710 + reparse_data->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR);
4711 /* This updates file_name_codepage which we need below. */
4712 int dbcs_p = max_filename_mbslen () > 1;
4607 4713
4608 /* According to MSDN, PrintNameLength does not include the 4714 /* According to MSDN, PrintNameLength does not include the
4609 terminating null character. */ 4715 terminating null character. */
@@ -4611,9 +4717,7 @@ readlink (const char *name, char *buf, size_t buf_size)
4611 memcpy (lwname, lwname_src, lwname_len); 4717 memcpy (lwname, lwname_src, lwname_len);
4612 lwname[lwname_len/sizeof(WCHAR)] = 0; /* null-terminate */ 4718 lwname[lwname_len/sizeof(WCHAR)] = 0; /* null-terminate */
4613 4719
4614 /* FIXME: Should we use the current file-name coding system 4720 lname_len = WideCharToMultiByte (file_name_codepage, 0, lwname, -1,
4615 instead of the fixed value of the ANSI codepage? */
4616 lname_len = WideCharToMultiByte (w32_ansi_code_page, 0, lwname, -1,
4617 lname, MAX_PATH, NULL, NULL); 4721 lname, MAX_PATH, NULL, NULL);
4618 if (!lname_len) 4722 if (!lname_len)
4619 { 4723 {
@@ -4639,18 +4743,33 @@ readlink (const char *name, char *buf, size_t buf_size)
4639 else 4743 else
4640 { 4744 {
4641 size_t size_to_copy = buf_size; 4745 size_t size_to_copy = buf_size;
4642 BYTE *p = lname; 4746 BYTE *p = lname, *p2;
4643 BYTE *pend = p + lname_len; 4747 BYTE *pend = p + lname_len;
4644 4748
4645 /* Normalize like dostounix_filename does, but we don't 4749 /* Normalize like dostounix_filename does, but we don't
4646 want to assume that lname is null-terminated. */ 4750 want to assume that lname is null-terminated. */
4647 if (*p && p[1] == ':' && *p >= 'A' && *p <= 'Z') 4751 if (dbcs_p)
4648 *p += 'a' - 'A'; 4752 p2 = CharNextExA (file_name_codepage, p, 0);
4753 else
4754 p2 = p + 1;
4755 if (*p && *p2 == ':' && *p >= 'A' && *p <= 'Z')
4756 {
4757 *p += 'a' - 'A';
4758 p += 2;
4759 }
4649 while (p <= pend) 4760 while (p <= pend)
4650 { 4761 {
4651 if (*p == '\\') 4762 if (*p == '\\')
4652 *p = '/'; 4763 *p = '/';
4653 ++p; 4764 if (dbcs_p)
4765 {
4766 p = CharNextExA (file_name_codepage, p, 0);
4767 /* CharNextExA doesn't advance at null character. */
4768 if (!*p)
4769 break;
4770 }
4771 else
4772 ++p;
4654 } 4773 }
4655 /* Testing for null-terminated LNAME is paranoia: 4774 /* Testing for null-terminated LNAME is paranoia:
4656 WideCharToMultiByte should always return a 4775 WideCharToMultiByte should always return a
@@ -4724,6 +4843,7 @@ chase_symlinks (const char *file)
4724 char link[MAX_PATH]; 4843 char link[MAX_PATH];
4725 ssize_t res, link_len; 4844 ssize_t res, link_len;
4726 int loop_count = 0; 4845 int loop_count = 0;
4846 int dbcs_p;
4727 4847
4728 if (is_windows_9x () == TRUE || !is_symlink (file)) 4848 if (is_windows_9x () == TRUE || !is_symlink (file))
4729 return (char *)file; 4849 return (char *)file;
@@ -4731,13 +4851,27 @@ chase_symlinks (const char *file)
4731 if ((link_len = GetFullPathName (file, MAX_PATH, link, NULL)) == 0) 4851 if ((link_len = GetFullPathName (file, MAX_PATH, link, NULL)) == 0)
4732 return (char *)file; 4852 return (char *)file;
4733 4853
4854 dbcs_p = max_filename_mbslen () > 1;
4734 target[0] = '\0'; 4855 target[0] = '\0';
4735 do { 4856 do {
4736 4857
4737 /* Remove trailing slashes, as we want to resolve the last 4858 /* Remove trailing slashes, as we want to resolve the last
4738 non-trivial part of the link name. */ 4859 non-trivial part of the link name. */
4739 while (link_len > 3 && IS_DIRECTORY_SEP (link[link_len-1])) 4860 if (!dbcs_p)
4740 link[link_len--] = '\0'; 4861 {
4862 while (link_len > 3 && IS_DIRECTORY_SEP (link[link_len-1]))
4863 link[link_len--] = '\0';
4864 }
4865 else if (link_len > 3)
4866 {
4867 char *n = CharPrevExA (file_name_codepage, link, link + link_len, 0);
4868
4869 while (n >= link + 2 && IS_DIRECTORY_SEP (*n))
4870 {
4871 n[1] = '\0';
4872 n = CharPrevExA (file_name_codepage, link, n, 0);
4873 }
4874 }
4741 4875
4742 res = readlink (link, target, MAX_PATH); 4876 res = readlink (link, target, MAX_PATH);
4743 if (res > 0) 4877 if (res > 0)
@@ -4750,8 +4884,21 @@ chase_symlinks (const char *file)
4750 the symlink, then copy the result back to target. */ 4884 the symlink, then copy the result back to target. */
4751 char *p = link + link_len; 4885 char *p = link + link_len;
4752 4886
4753 while (p > link && !IS_ANY_SEP (p[-1])) 4887 if (!dbcs_p)
4754 p--; 4888 {
4889 while (p > link && !IS_ANY_SEP (p[-1]))
4890 p--;
4891 }
4892 else
4893 {
4894 char *p1 = CharPrevExA (file_name_codepage, link, p, 0);
4895
4896 while (p > link && !IS_ANY_SEP (*p1))
4897 {
4898 p = p1;
4899 p1 = CharPrevExA (file_name_codepage, link, p1, 0);
4900 }
4901 }
4755 strcpy (p, target); 4902 strcpy (p, target);
4756 strcpy (target, link); 4903 strcpy (target, link);
4757 } 4904 }
@@ -6543,15 +6690,15 @@ sys_close (int fd)
6543 } 6690 }
6544 } 6691 }
6545 6692
6693 if (fd >= 0 && fd < MAXDESC)
6694 fd_info[fd].flags = 0;
6695
6546 /* Note that sockets do not need special treatment here (at least on 6696 /* Note that sockets do not need special treatment here (at least on
6547 NT and Windows 95 using the standard tcp/ip stacks) - it appears that 6697 NT and Windows 95 using the standard tcp/ip stacks) - it appears that
6548 closesocket is equivalent to CloseHandle, which is to be expected 6698 closesocket is equivalent to CloseHandle, which is to be expected
6549 because socket handles are fully fledged kernel handles. */ 6699 because socket handles are fully fledged kernel handles. */
6550 rc = _close (fd); 6700 rc = _close (fd);
6551 6701
6552 if (rc == 0 && fd < MAXDESC)
6553 fd_info[fd].flags = 0;
6554
6555 return rc; 6702 return rc;
6556} 6703}
6557 6704