Project

General

Profile

Bug #12906 » get-realpath.c

Mark Harris, 2020-06-28 12:39 AM

 
1
#include <sys/types.h>
2
#include <sys/stat.h>
3
#include <errno.h>
4
#include <fcntl.h>
5
#include <limits.h>
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <unistd.h>
9

    
10
int
11
main(int argc, char **argv)
12
{
13
    /* create file to be resolved */
14
    int f_fd = open("f", O_WRONLY | O_CREAT, 0666);
15
    if (f_fd == -1)
16
    {
17
        perror("Failed to create test file");
18
        return 1;
19
    }
20
    close(f_fd);
21

    
22
    int top_fd = open(".", O_RDONLY | O_DIRECTORY);
23
    if (top_fd == -1)
24
    {
25
        perror("Failed to open current directory");
26
        return 1;
27
    }
28

    
29
    /* create intermediate directories */
30
    int i_fd = top_fd;
31
    for (int i = 0; i < 100; ++i)
32
    {
33
        if (mkdirat(i_fd, "i", 0777) == -1 && errno != EEXIST)
34
        {
35
            perror("Failed to create intermediate directory");
36
            return 1;
37
        }
38
        int itmp_fd = openat(i_fd, "i", O_RDONLY | O_DIRECTORY);
39
        if (itmp_fd == -1)
40
        {
41
            perror("Failed to open intermediate directory");
42
            return 1;
43
        }
44
        if (i_fd != top_fd) close(i_fd);
45
        i_fd = itmp_fd;
46
    }
47

    
48
    /* create work directory */
49
    if (mkdir("w", 0777) == -1 && errno != EEXIST)
50
    {
51
        perror("Failed to create work directory");
52
        return 1;
53
    }
54
    if (chdir("w") == -1)
55
    {
56
        perror("Failed to change to work directory");
57
        return 1;
58
    }
59

    
60
    /* try to resolve path of file from within subdirectory */
61
    for (;;)
62
    {
63
        char resolved_name[PATH_MAX];
64

    
65
        if (renameat(top_fd, "w", i_fd, "w") == -1 && errno != ENOENT)
66
        {
67
            perror("Failed to rename work directory");
68
            return 1;
69
        }
70
        if (!realpath("../../../../../../../../../../../../../../../../../../"
71
                "../../../../../../../../../../../../../../../../../../../../"
72
                "../../../../../../../../../../../../../../../../../../../../"
73
                "../../../../../../../../../../../../../../../../../../../../"
74
                "../../../../../../../../../../../../../../../../../../../../"
75
                "../../../f", resolved_name) && errno != ENOENT)
76
        {
77
            perror("realpath");
78
            return 1;
79
        }
80
    }
81
}
(1-1/2)