OLD | NEW |
(Empty) | |
| 1 #include <stdlib.h> |
| 2 #include <limits.h> |
| 3 #include <sys/stat.h> |
| 4 #include <fcntl.h> |
| 5 #include <errno.h> |
| 6 #include <unistd.h> |
| 7 #include <string.h> |
| 8 #include "syscall.h" |
| 9 |
| 10 void __procfdname(char *, unsigned); |
| 11 |
| 12 char *realpath(const char *restrict filename, char *restrict resolved) |
| 13 { |
| 14 int fd; |
| 15 ssize_t r; |
| 16 struct stat st1, st2; |
| 17 char buf[15+3*sizeof(int)]; |
| 18 char tmp[PATH_MAX]; |
| 19 |
| 20 if (!filename) { |
| 21 errno = EINVAL; |
| 22 return 0; |
| 23 } |
| 24 |
| 25 fd = sys_open(filename, O_PATH|O_NONBLOCK|O_CLOEXEC); |
| 26 if (fd < 0) return 0; |
| 27 __procfdname(buf, fd); |
| 28 |
| 29 r = readlink(buf, tmp, sizeof tmp - 1); |
| 30 if (r < 0) goto err; |
| 31 tmp[r] = 0; |
| 32 |
| 33 fstat(fd, &st1); |
| 34 r = stat(tmp, &st2); |
| 35 if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) { |
| 36 if (!r) errno = ELOOP; |
| 37 goto err; |
| 38 } |
| 39 |
| 40 __syscall(SYS_close, fd); |
| 41 return resolved ? strcpy(resolved, tmp) : strdup(tmp); |
| 42 err: |
| 43 __syscall(SYS_close, fd); |
| 44 return 0; |
| 45 } |
OLD | NEW |