musl - musl - an implementation of the standard library for Linux-based systems

index : musl
musl - an implementation of the standard library for Linux-based systems
summary refs log tree commit diff
path: root/src/misc/realpath.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013年08月31日 15:50:23 -0400
committerRich Felker <dalias@aerifal.cx>2013年08月31日 15:50:23 -0400
commitdfddd43256f7ad4bad991eeff5cc51772595f327 (patch)
tree27e7540262ee86f9cdaaf283efb75230a75e3e89 /src/misc/realpath.c
parent27b4923ba00f0a7511c7ebf5f19313d6313052e9 (diff)
downloadmusl-dfddd43256f7ad4bad991eeff5cc51772595f327.tar.gz
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.
Diffstat (limited to 'src/misc/realpath.c')
-rw-r--r--src/misc/realpath.c 18
1 files changed, 6 insertions, 12 deletions
diff --git a/src/misc/realpath.c b/src/misc/realpath.c
index 2b846497..43d40183 100644
--- a/src/misc/realpath.c
+++ b/src/misc/realpath.c
@@ -5,6 +5,7 @@
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
+#include <string.h>
void __procfdname(char *, unsigned);
@@ -14,7 +15,7 @@ char *realpath(const char *restrict filename, char *restrict resolved)
ssize_t r;
struct stat st1, st2;
char buf[15+3*sizeof(int)];
- int alloc = 0;
+ char tmp[PATH_MAX];
if (!filename) {
errno = EINVAL;
@@ -25,27 +26,20 @@ char *realpath(const char *restrict filename, char *restrict resolved)
if (fd < 0) return 0;
__procfdname(buf, fd);
- if (!resolved) {
- alloc = 1;
- resolved = malloc(PATH_MAX);
- if (!resolved) return 0;
- }
-
- r = readlink(buf, resolved, PATH_MAX-1);
+ r = readlink(buf, tmp, sizeof tmp - 1);
if (r < 0) goto err;
- resolved[r] = 0;
+ tmp[r] = 0;
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) errno = ELOOP;
goto err;
}
close(fd);
- return resolved;
+ return resolved ? strcpy(resolved, tmp) : strdup(tmp);
err:
- if (alloc) free(resolved);
close(fd);
return 0;
}
generated by cgit v1.2.1 (git 2.18.0) at 2025年09月17日 18:10:29 +0000

AltStyle によって変換されたページ (->オリジナル) /