comparison src/realpath.c @ 4721:19d70297d866

Make readlink_or_correct_case function correctly on Darwin. src/ChangeLog addition: 2009-10-26 Aidan Kehoe <kehoea@parhasard.net> * config.h.in (REALPATH_CORRECTS_CASE): New #define, available on Darwin. * realpath.c (readlink_or_correct_case): On Darwin, use realpath(3)'s case correction to get the canonical case for a file; thank you Robert Delius Royar!
author Aidan Kehoe <kehoea@parhasard.net>
date Mon, 26 Oct 2009 09:42:20 +0000
parents d00888bfced1
children b3ea9c582280
comparison
equal deleted inserted replaced
4720:3c92890f3750 4721:19d70297d866
76 76
77 Returns length of characters copied info BUF. 77 Returns length of characters copied info BUF.
78 DOES NOT ZERO TERMINATE!!!!! 78 DOES NOT ZERO TERMINATE!!!!!
79 */ 79 */
80 80
81 #ifdef REALPATH_CORRECTS_CASE /* Darwin */
82 #include <sys/param.h>
83 #include <stdlib.h>
84 #endif
85
81 static int 86 static int
82 readlink_or_correct_case (const Ibyte *name, Ibyte *buf, Bytecount size, 87 readlink_or_correct_case (const Ibyte *name, Ibyte *buf, Bytecount size,
83 #ifndef WIN32_ANY 88 #ifndef WIN32_ANY
84 Boolint UNUSED (links_only) 89 Boolint UNUSED (links_only)
85 #else 90 #else
86 Boolint links_only 91 Boolint links_only
87 #endif 92 #endif
88 ) 93 )
89 { 94 {
90 #ifndef WIN32_ANY 95 #ifndef WIN32_ANY
96 #ifdef REALPATH_CORRECTS_CASE
97 /* Darwin's realpath corrects file name case, so we want to use that
98 here, as well as our own, non-case-correcting, implementation
99 further down in this file.
100
101 It might be reasonable to incorporate case correction in our own
102 realpath implementation, which would help things with
103 case-insensitive file systems on Linux; one way to do this would
104 be to make sure that init_initial_directory and
105 get_initial_directory always give the correct case. */
106 int n = qxe_readlink (name, buf, (size_t) size);
107 Extbyte realpath_buf[PATH_MAX], *tmp;
108 DECLARE_EISTRING (realpathing);
109
110 if (n >= 0 || errno != EINVAL)
111 return n;
112
113 eicpy_rawz (realpathing, name);
114 eito_external (realpathing, Qfile_name);
115 tmp = realpath (eiextdata (realpathing), realpath_buf);
116
117 if (!tmp)
118 return -1;
119
120 if (0 == memcmp (eiextdata (realpathing), realpath_buf,
121 eiextlen (realpathing)))
122 {
123 /* No case change needed; tell the caller that. */
124 errno = EINVAL;
125 return -1;
126 }
127
128 eireset (realpathing);
129 eicpy_ext (realpathing, realpath_buf, Qfile_name);
130 if (eilen (realpathing) > size)
131 {
132 errno = ERANGE;
133 return -1;
134 }
135
136 memcpy (buf, eidata (realpathing), eilen (realpathing));
137 return eilen (realpathing);
138 #else /* !REALPATH_CORRECTS_CASE */
91 return qxe_readlink (name, buf, (size_t) size); 139 return qxe_readlink (name, buf, (size_t) size);
92 #else 140 #endif /* REALPATH_CORRECTS_CASE */
141 #else /* defined (WIN32_ANY) */
93 # ifdef CYGWIN 142 # ifdef CYGWIN
94 Ibyte *tmp; 143 Ibyte *tmp;
95 int n = qxe_readlink (name, buf, (size_t) size); 144 int n = qxe_readlink (name, buf, (size_t) size);
96 if (n >= 0 || errno != EINVAL) 145 if (n >= 0 || errno != EINVAL)
97 return n; 146 return n;