1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Author: Aleksa Sarai <cyphar@cyphar.com>
4 * Copyright (C) 2018-2019 SUSE LLC.
17 bool needs_openat2(const struct open_how
*how
)
19 return how
->resolve
!= 0;
22 int raw_openat2(int dfd
, const char *path
, void *how
, size_t size
)
24 int ret
= syscall(__NR_openat2
, dfd
, path
, how
, size
);
25 return ret
>= 0 ? ret
: -errno
;
28 int sys_openat2(int dfd
, const char *path
, struct open_how
*how
)
30 return raw_openat2(dfd
, path
, how
, sizeof(*how
));
33 int sys_openat(int dfd
, const char *path
, struct open_how
*how
)
35 int ret
= openat(dfd
, path
, how
->flags
, how
->mode
);
36 return ret
>= 0 ? ret
: -errno
;
39 int sys_renameat2(int olddirfd
, const char *oldpath
,
40 int newdirfd
, const char *newpath
, unsigned int flags
)
42 int ret
= syscall(__NR_renameat2
, olddirfd
, oldpath
,
43 newdirfd
, newpath
, flags
);
44 return ret
>= 0 ? ret
: -errno
;
47 int touchat(int dfd
, const char *path
)
49 int fd
= openat(dfd
, path
, O_CREAT
);
55 char *fdreadlink(int fd
)
59 E_asprintf(&tmp
, "/proc/self/fd/%d", fd
);
61 target
= malloc(PATH_MAX
);
63 ksft_exit_fail_msg("fdreadlink: malloc failed\n");
64 memset(target
, 0, PATH_MAX
);
66 E_readlink(tmp
, target
, PATH_MAX
);
71 bool fdequal(int fd
, int dfd
, const char *path
)
73 char *fdpath
, *dfdpath
, *other
;
76 fdpath
= fdreadlink(fd
);
77 dfdpath
= fdreadlink(dfd
);
80 E_asprintf(&other
, "%s", dfdpath
);
81 else if (*path
== '/')
82 E_asprintf(&other
, "%s", path
);
84 E_asprintf(&other
, "%s/%s", dfdpath
, path
);
86 cmp
= !strcmp(fdpath
, other
);
94 bool openat2_supported
= false;
96 void __attribute__((constructor
)) init(void)
98 struct open_how how
= {};
101 BUILD_BUG_ON(sizeof(struct open_how
) != OPEN_HOW_SIZE_VER0
);
103 /* Check openat2(2) support. */
104 fd
= sys_openat2(AT_FDCWD
, ".", &how
);
105 openat2_supported
= (fd
>= 0);