From 43ea4849373d263db6d8eb42e52ffe7e1b0fbbbc Mon Sep 17 00:00:00 2001 From: Vincent Torri Date: Tue, 3 Jul 2012 08:57:07 +0000 Subject: [PATCH] * AUTHORS: * src/lib/evil_stdlib.c: * src/lib/evil_stdlib.h: Update realpath() code, based on Keith Marshall's implementation. SVN revision: 73212 --- legacy/evil/AUTHORS | 1 + legacy/evil/ChangeLog | 7 ++++ legacy/evil/src/lib/evil_stdlib.c | 64 ++++++++++++++++++++++++++++++- legacy/evil/src/lib/evil_stdlib.h | 8 ++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/legacy/evil/AUTHORS b/legacy/evil/AUTHORS index cee8fc9f11..54911d18d2 100644 --- a/legacy/evil/AUTHORS +++ b/legacy/evil/AUTHORS @@ -6,3 +6,4 @@ Main Authors: Paul Vixie (ISC) (inet_pton and inet_ntop functions) Daniel Stenberg (inet_pton and inet_ntop functions) The MinGW and MinGW-w64 teams (POSIX printf family functions) + Keith Marshall (realpath on Windows XP). See http://sourceforge.net/tracker/?func=detail&atid=302435&aid=1294010&group_id=2435 diff --git a/legacy/evil/ChangeLog b/legacy/evil/ChangeLog index d7f5e7bd13..9beb471d40 100644 --- a/legacy/evil/ChangeLog +++ b/legacy/evil/ChangeLog @@ -1,3 +1,10 @@ +2012-07-03 Vincent Torri + + * AUTHORS: + * src/lib/evil_stdlib.c: + * src/lib/evil_stdlib.h: + Update realpath() code, based on Keith Marshall's implementation. + 2012-04-26 Vincent Torri * NEWS: diff --git a/legacy/evil/src/lib/evil_stdlib.c b/legacy/evil/src/lib/evil_stdlib.c index 11a33103f7..d22a7dc71e 100644 --- a/legacy/evil/src/lib/evil_stdlib.c +++ b/legacy/evil/src/lib/evil_stdlib.c @@ -362,7 +362,69 @@ char * realpath(const char *file_name, char *resolved_name) { #ifndef __MINGW32CE__ - return _fullpath(resolved_name, file_name, PATH_MAX); + char *retname = NULL; /* we will return this, if we fail */ + + /* SUSv3 says we must set `errno = EINVAL', and return NULL, + * if `name' is passed as a NULL pointer. + */ + + if (file_name == NULL) + errno = EINVAL; + + /* Otherwise, `name' must refer to a readable filesystem object, + * if we are going to resolve its absolute path name. + */ + + else if (access(file_name, 4) == 0) + { + /* If `name' didn't point to an existing entity, + * then we don't get to here; we simply fall past this block, + * returning NULL, with `errno' appropriately set by `access'. + * + * When we _do_ get to here, then we can use `_fullpath' to + * resolve the full path for `name' into `resolved', but first, + * check that we have a suitable buffer, in which to return it. + */ + + if ((retname = resolved_name) == NULL) + { + /* Caller didn't give us a buffer, so we'll exercise the + * option granted by SUSv3, and allocate one. + * + * `_fullpath' would do this for us, but it uses `malloc', and + * Microsoft's implementation doesn't set `errno' on failure. + * If we don't do this explicitly ourselves, then we will not + * know if `_fullpath' fails on `malloc' failure, or for some + * other reason, and we want to set `errno = ENOMEM' for the + * `malloc' failure case. + */ + + retname = malloc(_MAX_PATH); + } + + /* By now, we should have a valid buffer. + * If we don't, then we know that `malloc' failed, + * so we can set `errno = ENOMEM' appropriately. + */ + + if (retname == NULL) + errno = ENOMEM; + + /* Otherwise, when we do have a valid buffer, + * `_fullpath' should only fail if the path name is too long. + */ + + else if ((retname = _fullpath(retname, file_name, _MAX_PATH)) == NULL) + errno = ENAMETOOLONG; + } + + /* By the time we get to here, + * `retname' either points to the required resolved path name, + * or it is NULL, with `errno' set appropriately, either of which + * is our required return condition. + */ + + return retname; #else char cwd[PATH_MAX]; size_t l1; diff --git a/legacy/evil/src/lib/evil_stdlib.h b/legacy/evil/src/lib/evil_stdlib.h index 96a0ae9fe6..81d564f86f 100644 --- a/legacy/evil/src/lib/evil_stdlib.h +++ b/legacy/evil/src/lib/evil_stdlib.h @@ -175,6 +175,14 @@ EAPI int mkstemp(char *__template); * That function can be used to obtain the absolute path name for * relative paths (relPath) that include "./" or "../" in their names. * + * On Windows XP, errno is set in the following cases: + * + * @li EACCESS: if @p file_name can not be accessed. + * @li EINVAL: if @p file_name is @c NULL. + * @li ENAMETOOLONG: if the path name is too long. + * @li ENOENT: @p file_name does not exist + * @li ENOMEM: if memory allocation fails. + * * Conformity: None. * * Supported OS: Windows XP, Windows CE.