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