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 <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) |
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; |
return 0; |
||||
} |
} |
||||
|
|||||
Loading…
Reference in new issue