summaryrefslogtreecommitdiff
path: root/src/lib/libc/stdlib/realpath.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libc/stdlib/realpath.c')
-rw-r--r--src/lib/libc/stdlib/realpath.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/lib/libc/stdlib/realpath.c b/src/lib/libc/stdlib/realpath.c
index e349b7e068..d01b19e0f2 100644
--- a/src/lib/libc/stdlib/realpath.c
+++ b/src/lib/libc/stdlib/realpath.c
@@ -35,8 +35,7 @@
35 */ 35 */
36 36
37#if defined(LIBC_SCCS) && !defined(lint) 37#if defined(LIBC_SCCS) && !defined(lint)
38/*static char sccsid[] = "from: @(#)realpath.c 8.1 (Berkeley) 2/16/94";*/ 38static char *rcsid = "$OpenBSD: realpath.c,v 1.7 2002/05/24 21:22:37 deraadt Exp $";
39static char *rcsid = "$Id: realpath.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
40#endif /* LIBC_SCCS and not lint */ 39#endif /* LIBC_SCCS and not lint */
41 40
42#include <sys/param.h> 41#include <sys/param.h>
@@ -63,13 +62,18 @@ realpath(path, resolved)
63 struct stat sb; 62 struct stat sb;
64 int fd, n, rootd, serrno; 63 int fd, n, rootd, serrno;
65 char *p, *q, wbuf[MAXPATHLEN]; 64 char *p, *q, wbuf[MAXPATHLEN];
65 int symlinks = 0;
66 66
67 /* Save the starting point. */ 67 /* Save the starting point. */
68 if ((fd = open(".", O_RDONLY)) < 0) { 68 if ((fd = open(".", O_RDONLY)) < 0) {
69 (void)strcpy(resolved, "."); 69 (void)strlcpy(resolved, ".", MAXPATHLEN);
70 return (NULL); 70 return (NULL);
71 } 71 }
72 72
73 /* Convert "." -> "" to optimize away a needless lstat() and chdir() */
74 if (path[0] == '.' && path[1] == '\0')
75 path = "";
76
73 /* 77 /*
74 * Find the dirname and basename from the path to be resolved. 78 * Find the dirname and basename from the path to be resolved.
75 * Change directory to the dirname component. 79 * Change directory to the dirname component.
@@ -78,8 +82,7 @@ realpath(path, resolved)
78 * if it is a directory, then change to that directory. 82 * if it is a directory, then change to that directory.
79 * get the current directory name and append the basename. 83 * get the current directory name and append the basename.
80 */ 84 */
81 (void)strncpy(resolved, path, MAXPATHLEN - 1); 85 strlcpy(resolved, path, MAXPATHLEN);
82 resolved[MAXPATHLEN - 1] = '\0';
83loop: 86loop:
84 q = strrchr(resolved, '/'); 87 q = strrchr(resolved, '/');
85 if (q != NULL) { 88 if (q != NULL) {
@@ -99,9 +102,13 @@ loop:
99 p = resolved; 102 p = resolved;
100 103
101 /* Deal with the last component. */ 104 /* Deal with the last component. */
102 if (lstat(p, &sb) == 0) { 105 if (*p != '\0' && lstat(p, &sb) == 0) {
103 if (S_ISLNK(sb.st_mode)) { 106 if (S_ISLNK(sb.st_mode)) {
104 n = readlink(p, resolved, MAXPATHLEN); 107 if (++symlinks > MAXSYMLINKS) {
108 errno = ELOOP;
109 goto err1;
110 }
111 n = readlink(p, resolved, MAXPATHLEN-1);
105 if (n < 0) 112 if (n < 0)
106 goto err1; 113 goto err1;
107 resolved[n] = '\0'; 114 resolved[n] = '\0';
@@ -118,7 +125,7 @@ loop:
118 * Save the last component name and get the full pathname of 125 * Save the last component name and get the full pathname of
119 * the current directory. 126 * the current directory.
120 */ 127 */
121 (void)strcpy(wbuf, p); 128 (void)strlcpy(wbuf, p, sizeof wbuf);
122 if (getcwd(resolved, MAXPATHLEN) == 0) 129 if (getcwd(resolved, MAXPATHLEN) == 0)
123 goto err1; 130 goto err1;
124 131