+2019-07-02 Bruno Haible <bruno@clisp.org>
+
+ getcwd: Fix crash when invoked with size = 0 on MSVC.
+ * lib/getcwd.c: Include msvc-inval.h.
+ (getcwd_nothrow): New function/macro.
+ (getcwd_system): New macro.
+ (__getcwd): Use it instead of getcwd.
+ * modules/getcwd (Depends-on): Add msvc-inval.
+ * doc/posix-functions/getcwd.texi: Mention the MSVC issue.
+
2019-07-02 Bruno Haible <bruno@clisp.org>
nonblocking-pipe tests: Fix test failure on MSVC.
headers, and the declaration is missing from @code{<unistd.h>}:
mingw, MSVC 14.
@item
+On some platforms, @code{getcwd (buf, 0)} crashes:
+MSVC 14.
+@item
On some platforms, @code{getcwd (buf, 0)} fails with @code{ERANGE}
instead of the required @code{EINVAL}:
-mingw, MSVC 14.
+mingw.
@end itemize
Portability problems fixed by Gnulib module @code{getcwd}:
# define MATCHING_INO(dp, ino) true
#endif
+#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+# include "msvc-inval.h"
+#endif
+
#if !_LIBC
# define __getcwd rpl_getcwd
# define __lstat lstat
# undef closedir
#endif
\f
+#ifdef _MSC_VER
+# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+static char *
+getcwd_nothrow (char *buf, size_t size)
+{
+ char *result;
+
+ TRY_MSVC_INVAL
+ {
+ result = _getcwd (buf, size);
+ }
+ CATCH_MSVC_INVAL
+ {
+ result = NULL;
+ errno = ERANGE;
+ }
+ DONE_MSVC_INVAL;
+
+ return result;
+}
+# else
+# define getcwd_nothrow _getcwd
+# endif
+# define getcwd_system getcwd_nothrow
+#else
+# define getcwd_system getcwd
+#endif
+
/* Get the name of the current working directory, and put it in SIZE
bytes of BUF. Returns NULL if the directory couldn't be determined or
SIZE was too small. If successful, returns BUF. In GNU, if BUF is
this wrong result with errno = 0. */
# undef getcwd
- dir = getcwd (buf, size);
+ dir = getcwd_system (buf, size);
if (dir || (size && errno == ERANGE))
return dir;
if (errno == EINVAL && buf == NULL && size == 0)
{
char big_buffer[BIG_FILE_NAME_LENGTH + 1];
- dir = getcwd (big_buffer, sizeof big_buffer);
+ dir = getcwd_system (big_buffer, sizeof big_buffer);
if (dir)
return strdup (dir);
}
unistd
extensions
pathmax [test $REPLACE_GETCWD = 1]
+msvc-inval [test $REPLACE_GETCWD = 1]
mempcpy [test $REPLACE_GETCWD = 1]
d-ino [test $REPLACE_GETCWD = 1]
memmove [test $REPLACE_GETCWD = 1]