提交 dfddd432 编写于 作者: R Rich Felker

debloat realpath's allocation strategy

rather than allocating a PATH_MAX-sized buffer when the caller does
not provide an output buffer, work first with a PATH_MAX-sized temp
buffer with automatic storage, and either copy it to the caller's
buffer or strdup it on success. this not only avoids massive memory
waste, but also avoids pulling in free (and thus the full malloc
implementation) unnecessarily in static programs.
上级 27b4923b
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
void __procfdname(char *, unsigned); void __procfdname(char *, unsigned);
...@@ -14,7 +15,7 @@ char *realpath(const char *restrict filename, char *restrict resolved) ...@@ -14,7 +15,7 @@ char *realpath(const char *restrict filename, char *restrict resolved)
ssize_t r; ssize_t r;
struct stat st1, st2; struct stat st1, st2;
char buf[15+3*sizeof(int)]; char buf[15+3*sizeof(int)];
int alloc = 0; char tmp[PATH_MAX];
if (!filename) { if (!filename) {
errno = EINVAL; errno = EINVAL;
...@@ -25,27 +26,20 @@ char *realpath(const char *restrict filename, char *restrict resolved) ...@@ -25,27 +26,20 @@ char *realpath(const char *restrict filename, char *restrict resolved)
if (fd < 0) return 0; if (fd < 0) return 0;
__procfdname(buf, fd); __procfdname(buf, fd);
if (!resolved) { r = readlink(buf, tmp, sizeof tmp - 1);
alloc = 1;
resolved = malloc(PATH_MAX);
if (!resolved) return 0;
}
r = readlink(buf, resolved, PATH_MAX-1);
if (r < 0) goto err; if (r < 0) goto err;
resolved[r] = 0; tmp[r] = 0;
fstat(fd, &st1); fstat(fd, &st1);
r = stat(resolved, &st2); r = stat(tmp, &st2);
if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) { if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
if (!r) errno = ELOOP; if (!r) errno = ELOOP;
goto err; goto err;
} }
close(fd); close(fd);
return resolved; return resolved ? strcpy(resolved, tmp) : strdup(tmp);
err: err:
if (alloc) free(resolved);
close(fd); close(fd);
return 0; return 0;
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册