aboutsummaryrefslogtreecommitdiffstats
path: root/test/test-openat.c
blob: b710285c343b0b2a18c80401020b8bde4c1a1372 (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
50
51
52
53
54
55
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>

char *path_of(int fd) {
    ssize_t len;
    char proc[PATH_MAX], real[PATH_MAX];
    snprintf(proc, sizeof(proc), "/proc/self/fd/%d", fd);
    len = readlink(proc, real, sizeof(real));
    real[len] = '\0';
    return strdup(real);
}

/*
* Test that recusing up the tree with openat(fd, "../") handles slashes
* correctly and doesn't end up opening the same directory instead of going up a
* level.
*/
int main () {
    int fd, dir_fd;
    struct stat st;
    ino_t ino;
    char *path;

    fd = openat(AT_FDCWD, ".", O_DIRECTORY, 0);
    fstat(fd, &st);
    ino = st.st_ino;

    while (1) {
        path = path_of(fd);
        //puts(path);

        dir_fd = openat(fd, "../", O_DIRECTORY, 0);
        fstat(dir_fd, &st);
        if (st.st_ino == ino) {
            if (strcmp(path, "/") == 0) {
                //puts("Reached top of tree");
                return 0;
            } else {
                //puts("Recursion failed!");
                return 1;
            }
        }

        free (path);
        ino = st.st_ino;
        fd = dir_fd;
    }
    return 0;
}