github.com/afumu/libc@v0.0.6/musl/src/misc/realpath.c (about)

     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  char *realpath(const char *restrict filename, char *restrict resolved)
    11  {
    12  	int fd;
    13  	ssize_t r;
    14  	struct stat st1, st2;
    15  	char buf[15+3*sizeof(int)];
    16  	char tmp[PATH_MAX];
    17  
    18  	if (!filename) {
    19  		errno = EINVAL;
    20  		return 0;
    21  	}
    22  
    23  	fd = sys_open(filename, O_PATH|O_NONBLOCK|O_CLOEXEC);
    24  	if (fd < 0) return 0;
    25  	__procfdname(buf, fd);
    26  
    27  	r = readlink(buf, tmp, sizeof tmp - 1);
    28  	if (r < 0) goto err;
    29  	tmp[r] = 0;
    30  
    31  	fstat(fd, &st1);
    32  	r = stat(tmp, &st2);
    33  	if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
    34  		if (!r) errno = ELOOP;
    35  		goto err;
    36  	}
    37  
    38  	__syscall(SYS_close, fd);
    39  	return resolved ? strcpy(resolved, tmp) : strdup(tmp);
    40  err:
    41  	__syscall(SYS_close, fd);
    42  	return 0;
    43  }