blob: 1474b1e501c159f17bf60d07e0c13bbeaaaece8d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
/*
* Note that this requires name to refer to an existing file. This is
* correct according to POSIX. However, BSD and GNU implementations
* also allow name to refer to a non-existing file in an existing
* directory.
*/
char *realpath(const char *name, char *resolved_name)
{
static const char proc_fd_prefix[] = "/proc/self/fd/";
char proc_fd_name[sizeof(proc_fd_prefix) + sizeof(int) * 3];
int allocated = 0;
int fd;
ssize_t len;
/* Open for path lookup only */
fd = open(name, O_PATH);
if (fd < 0)
return NULL;
if (!resolved_name) {
resolved_name = malloc(PATH_MAX);
if (!resolved_name)
goto out_close;
allocated = 1;
}
/* Use procfs to read back the resolved name */
sprintf(proc_fd_name, "%s%d", proc_fd_prefix, fd);
len = readlink(proc_fd_name, resolved_name, PATH_MAX - 1);
if (len < 0) {
if (allocated)
free(resolved_name);
resolved_name = NULL;
} else {
resolved_name[len] = 0;
}
out_close:
close(fd);
return resolved_name;
}
|