blob: 35597a13c18234e5b48d72dc2da26df18620cdbe [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org>
*/
/*\
* [DESCRIPTION]
*
* Basic open_by_handle_at() tests.
*
* [ALGORITHM]
* - Check that we were able to access a file's stat which is opened with
* open_by_handle_at().
\*/
#define _GNU_SOURCE
#include <fcntl.h>
#include <sys/stat.h>
#include "lapi/name_to_handle_at.h"
#define TEST_FILE "test_file"
#define TEST_DIR "test_dir"
static int dir_fd, fd_atcwd = AT_FDCWD, file_fd;
static struct file_handle *fhp;
static struct tcase {
int *dfd;
const char *pathname;
int name_flags;
int flags;
} tcases[] = {
{&dir_fd, TEST_FILE, 0, O_RDWR},
{&dir_fd, TEST_FILE, 0, O_RDONLY},
{&dir_fd, TEST_FILE, 0, O_WRONLY},
{&dir_fd, TEST_FILE, AT_EMPTY_PATH, O_RDWR},
{&dir_fd, TEST_FILE, AT_EMPTY_PATH, O_RDONLY},
{&dir_fd, TEST_FILE, AT_EMPTY_PATH, O_WRONLY},
{&dir_fd, TEST_FILE, AT_SYMLINK_FOLLOW, O_RDWR},
{&dir_fd, TEST_FILE, AT_SYMLINK_FOLLOW, O_RDONLY},
{&dir_fd, TEST_FILE, AT_SYMLINK_FOLLOW, O_WRONLY},
{&dir_fd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_RDWR},
{&dir_fd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_RDONLY},
{&dir_fd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_WRONLY},
{&dir_fd, "", AT_EMPTY_PATH, O_RDONLY},
{&file_fd, "", AT_EMPTY_PATH, O_RDONLY},
{&fd_atcwd, TEST_FILE, 0, O_RDWR},
{&fd_atcwd, TEST_FILE, 0, O_RDONLY},
{&fd_atcwd, TEST_FILE, 0, O_WRONLY},
{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH, O_RDWR},
{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH, O_RDONLY},
{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH, O_WRONLY},
{&fd_atcwd, TEST_FILE, AT_SYMLINK_FOLLOW, O_RDWR},
{&fd_atcwd, TEST_FILE, AT_SYMLINK_FOLLOW, O_RDONLY},
{&fd_atcwd, TEST_FILE, AT_SYMLINK_FOLLOW, O_WRONLY},
{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_RDWR},
{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_RDONLY},
{&fd_atcwd, TEST_FILE, AT_EMPTY_PATH | AT_SYMLINK_FOLLOW, O_WRONLY},
{&fd_atcwd, "", AT_EMPTY_PATH, O_RDONLY},
};
static void cleanup(void)
{
SAFE_CLOSE(dir_fd);
SAFE_CLOSE(file_fd);
}
static void setup(void)
{
SAFE_MKDIR(TEST_DIR, 0700);
dir_fd = SAFE_OPEN(TEST_DIR, O_DIRECTORY);
SAFE_CHDIR(TEST_DIR);
SAFE_TOUCH(TEST_FILE, 0600, NULL);
file_fd = SAFE_OPEN("foo_file", O_RDWR | O_CREAT);
fhp = allocate_file_handle(AT_FDCWD, TEST_FILE);
}
static void run(unsigned int n)
{
struct tcase *tc = &tcases[n];
struct stat file_stat;
int fd, mount_id;
TEST(name_to_handle_at(*tc->dfd, tc->pathname, fhp, &mount_id,
tc->name_flags));
if (TST_RET) {
tst_res(TFAIL | TTERRNO, "name_to_handle_at() failed (%d)", n);
return;
}
TEST(fd = open_by_handle_at(*tc->dfd, fhp, tc->flags));
if (fd < 0) {
tst_res(TFAIL | TTERRNO, "open_by_handle_at() failed (%d)", n);
return;
}
SAFE_FSTAT(fd, &file_stat);
/* Don't check stats when pathname is empty */
if (file_stat.st_size == 0 || !tc->pathname[0])
tst_res(TPASS, "open_by_handle_at() passed (%d)", n);
else
tst_res(TFAIL, "fstat() didn't work as expected (%d)", n);
SAFE_CLOSE(fd);
}
static struct tst_test test = {
.tcnt = ARRAY_SIZE(tcases),
.test = run,
.setup = setup,
.cleanup = cleanup,
.needs_tmpdir = 1,
.needs_root = 1,
};