use new realpath code

This commit is contained in:
Kelvin Sherlock 2014-12-22 09:53:38 -05:00
parent 1e7139ddbf
commit f1566cce45
3 changed files with 25 additions and 8 deletions

View File

@ -22,6 +22,7 @@ set(TOOLBOX_SRC
pathnames.cpp
utility.cpp
fs_spec.cpp
realpath.c
)

View File

@ -59,6 +59,9 @@
using ToolBox::Log;
using MacOS::macos_error_from_errno;
extern "C" {
char * fs_spec_realpath(const char * __restrict path, char * __restrict resolved);
}
namespace OS {
@ -83,15 +86,10 @@ namespace OS {
// realpath does not behave in such a manner.
// expand the path. Also handles relative paths.
char *cp = ::realpath(path.c_str(), buffer);
char *cp = ::fs_spec_realpath(path.c_str(), buffer);
if (!cp)
{
// temporary workaround - return if it's just a filename w/o a path.
if (path.find('/') == path.npos) return path;
fprintf(stderr, "realpath failed %s\n", path.c_str());
return "";
}

View File

@ -32,7 +32,7 @@ static char sccsid[] = "@(#)realpath.c 8.1 (Berkeley) 2/16/94";
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "namespace.h"
//#include "namespace.h"
#include <sys/param.h>
#include <sys/stat.h>
@ -40,15 +40,23 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "un-namespace.h"
//#include "un-namespace.h"
#define FS_SPEC
/*
* Find the real name of path, by removing all ".", ".." and symlink
* components. Returns (resolved) on success, or (NULL) on failure,
* in which case the path which caused trouble is left in (resolved).
*/
#ifdef FS_SPEC
char *
fs_spec_realpath(const char * __restrict path, char * __restrict resolved)
#else
char *
realpath(const char * __restrict path, char * __restrict resolved)
#endif
{
struct stat sb;
char *p, *q, *s;
@ -57,6 +65,10 @@ realpath(const char * __restrict path, char * __restrict resolved)
int m, slen;
char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
#ifdef FS_SPEC
int serrno = errno;
#endif
if (path == NULL) {
errno = EINVAL;
return (NULL);
@ -162,6 +174,12 @@ realpath(const char * __restrict path, char * __restrict resolved)
return (NULL);
}
if (lstat(resolved, &sb) != 0) {
#ifdef FS_SPEC
if (errno == ENOENT && p == NULL) {
errno = serrno;
return (resolved);
}
#endif
if (m)
free(resolved);
return (NULL);