mirror of https://git.musl-libc.org/git/musl
Browse Source
clean and simple, but fails when the caller does not have permissions to open the file for reading or when /proc is not available. i may replace this with a full implementation later, possibly leaving this version as an optimization to use when it works.rs-1.0
1 changed files with 43 additions and 0 deletions
@ -1,6 +1,49 @@ |
|||
#include <stdlib.h> |
|||
#include <stdio.h> |
|||
#include <limits.h> |
|||
#include <sys/stat.h> |
|||
#include <fcntl.h> |
|||
#include <errno.h> |
|||
#include <unistd.h> |
|||
|
|||
char *realpath(const char *filename, char *resolved) |
|||
{ |
|||
int fd; |
|||
ssize_t r; |
|||
struct stat st1, st2; |
|||
char buf[15+3*sizeof(int)]; |
|||
int alloc = 0; |
|||
|
|||
if (!filename) { |
|||
errno = EINVAL; |
|||
return 0; |
|||
} |
|||
|
|||
if (!resolved) { |
|||
alloc = 1; |
|||
resolved = malloc(PATH_MAX); |
|||
if (!resolved) return 0; |
|||
} |
|||
|
|||
fd = open(filename, O_RDONLY|O_NONBLOCK); |
|||
if (fd < 0) return 0; |
|||
snprintf(buf, sizeof buf, "/proc/self/fd/%d", fd); |
|||
|
|||
r = readlink(buf, resolved, PATH_MAX-1); |
|||
if (r < 0) goto err; |
|||
resolved[r] = 0; |
|||
|
|||
fstat(fd, &st1); |
|||
r = stat(resolved, &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; |
|||
err: |
|||
if (alloc) free(resolved); |
|||
close(fd); |
|||
return 0; |
|||
} |
|||
|
|||
Loading…
Reference in new issue