X-Git-Url: https://git.saurik.com/apple/libc.git/blobdiff_plain/3d9156a7a519a5e3aa1b92e9d9d4b991f1aed7ff..7ba935f9833da45a0dbcb06329e3015acee97223:/stdlib/FreeBSD/realpath.c.patch diff --git a/stdlib/FreeBSD/realpath.c.patch b/stdlib/FreeBSD/realpath.c.patch index dd06685..2d154b1 100644 --- a/stdlib/FreeBSD/realpath.c.patch +++ b/stdlib/FreeBSD/realpath.c.patch @@ -1,6 +1,6 @@ ---- realpath.c.orig 2003-08-15 19:22:17.000000000 -0700 -+++ realpath.c 2004-12-04 14:47:52.000000000 -0800 -@@ -35,13 +35,35 @@ +--- realpath.c.orig 2008-04-04 14:39:39.000000000 -0700 ++++ realpath.c 2008-04-04 19:59:19.000000000 -0700 +@@ -35,13 +35,41 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ #include "namespace.h" #include #include @@ -23,7 +23,8 @@ + char buf[PATH_MAX]; +}; + -+static struct attrlist alist = { ++#ifndef BUILDING_VARIANT ++__private_extern__ struct attrlist _rp_alist = { + ATTR_BIT_MAP_COUNT, + 0, + ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID, @@ -32,13 +33,21 @@ + 0, + 0, +}; ++#else /* BUILDING_VARIANT */ ++__private_extern__ struct attrlist _rp_alist; ++#endif /* BUILDING_VARIANT */ ++ ++extern char * __private_getcwd(char *, size_t, int); + /* * char *realpath(const char *path, char resolved[PATH_MAX]); * -@@ -52,13 +74,25 @@ +@@ -50,26 +78,67 @@ __FBSDID("$FreeBSD: src/lib/libc/stdlib/ + * in which case the path which caused trouble is left in (resolved). + */ char * - realpath(const char *path, char resolved[PATH_MAX]) +-realpath(const char *path, char resolved[PATH_MAX]) ++realpath(const char *path, char inresolved[PATH_MAX]) { + struct attrs attrs; struct stat sb; @@ -54,30 +63,73 @@ + static dev_t rootdev; + static int rootdev_inited = 0; + ino_t inode; ++ char *resolved; ++ if (path == NULL) { ++ errno = EINVAL; ++ return (NULL); ++ } ++#if __DARWIN_UNIX03 ++ if (*path == 0) { ++ errno = ENOENT; ++ return (NULL); ++ } ++#endif /* __DARWIN_UNIX03 */ ++ /* ++ * Extension to the standard; if inresolved == NULL, allocate memory ++ * (first on the stack, then use strdup()) ++ */ ++ if (!inresolved) { ++ if ((resolved = alloca(PATH_MAX)) == NULL) return (NULL); ++ } else { ++ resolved = inresolved; ++ } + if (!rootdev_inited) { + rootdev_inited = 1; -+ if (stat("/", &sb) < 0) ++ if (stat("/", &sb) < 0) { + return (NULL); ++ } + rootdev = sb.st_dev; + } serrno = errno; symlinks = 0; if (path[0] == '/') { -@@ -80,6 +114,12 @@ + resolved[0] = '/'; + resolved[1] = '\0'; +- if (path[1] == '\0') ++ if (path[1] == '\0') { + return (resolved); ++ } + resolved_len = 1; + left_len = strlcpy(left, path + 1, sizeof(left)); + } else { +- if (getcwd(resolved, PATH_MAX) == NULL) { ++#if !defined(VARIANT_DARWINEXTSN) && __DARWIN_UNIX03 ++ /* 4447159: don't use GETPATH, so this will fail if */ ++ /* if parent directories are not readable, as per POSIX */ ++ if (__private_getcwd(resolved, PATH_MAX, 0) == NULL) ++#else /* VARIANT_DARWINEXTSN || !__DARWIN_UNIX03 */ ++ if (__private_getcwd(resolved, PATH_MAX, 1) == NULL) ++#endif /* !VARIANT_DARWINEXTSN && __DARWIN_UNIX03 */ ++ { + strlcpy(resolved, ".", PATH_MAX); + return (NULL); + } +@@ -80,6 +149,13 @@ realpath(const char *path, char resolved errno = ENAMETOOLONG; return (NULL); } + if (resolved_len > 1) { -+ if (stat(resolved, &sb) < 0) ++ if (stat(resolved, &sb) < 0) { + return (NULL); ++ } + lastdev = sb.st_dev; + } else + lastdev = rootdev; /* * Iterate over path components in `left'. -@@ -127,6 +167,13 @@ +@@ -127,6 +203,13 @@ realpath(const char *path, char resolved } /* @@ -91,17 +143,17 @@ * Append the next path component and lstat() it. If * lstat() fails we still can return successfully if * there are no more path components left. -@@ -136,14 +183,72 @@ +@@ -136,25 +219,87 @@ realpath(const char *path, char resolved errno = ENAMETOOLONG; return (NULL); } - if (lstat(resolved, &sb) != 0) { -+ if (getattrlist(resolved, &alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { ++ if (getattrlist(resolved, &_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) { + useattrs = 1; + islink = (attrs.type == VLNK); + dev = attrs.dev; + inode = attrs.id.fid_objno; -+ } else if (errno == EOPNOTSUPP || errno == EINVAL) { ++ } else if (errno == ENOTSUP || errno == EINVAL) { + if ((useattrs = lstat(resolved, &sb)) == 0) { + islink = S_ISLNK(sb.st_mode); + dev = sb.st_dev; @@ -110,10 +162,12 @@ + } else + useattrs = -1; + if (useattrs < 0) { ++#if !__DARWIN_UNIX03 if (errno == ENOENT && p == NULL) { errno = serrno; return (resolved); } ++#endif /* !__DARWIN_UNIX03 */ return (NULL); } - if (S_ISLNK(sb.st_mode)) { @@ -137,7 +191,7 @@ + * that each component of the mountpoint + * is a directory (and not a symlink) + */ -+ char temp[MNAMELEN]; ++ char temp[sizeof(sfs.f_mntonname)]; + char *cp; + int ok = 1; + @@ -166,7 +220,13 @@ if (symlinks++ > MAXSYMLINKS) { errno = ELOOP; return (NULL); -@@ -155,6 +260,7 @@ + } + slen = readlink(resolved, symlink, sizeof(symlink) - 1); +- if (slen < 0) ++ if (slen < 0) { + return (NULL); ++ } + symlink[slen] = '\0'; if (symlink[0] == '/') { resolved[1] = 0; resolved_len = 1; @@ -174,7 +234,7 @@ } else if (resolved_len > 1) { /* Strip the last path component. */ resolved[resolved_len - 1] = '\0'; -@@ -184,7 +290,30 @@ +@@ -184,7 +329,30 @@ realpath(const char *path, char resolved } } left_len = strlcpy(left, symlink, sizeof(left)); @@ -205,3 +265,10 @@ } /* +@@ -193,5 +361,6 @@ realpath(const char *path, char resolved + */ + if (resolved_len > 1 && resolved[resolved_len - 1] == '/') + resolved[resolved_len - 1] = '\0'; ++ if (!inresolved) resolved = strdup(resolved); + return (resolved); + }