tools/testing/selftests/fchmodat2/fchmodat2_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/fchmodat2/fchmodat2_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/fchmodat2/fchmodat2_test.c
Extension
.c
Size
4199 bytes
Lines
201
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct testdir {
	char *dirname;
	int dfd;
};

int sys_fchmodat2(int dfd, const char *filename, mode_t mode, int flags)
{
	int ret = syscall(__NR_fchmodat2, dfd, filename, mode, flags);

	return ret >= 0 ? ret : -errno;
}

static void setup_testdir(struct testdir *testdir)
{
	int ret, dfd;
	char dirname[] = "/tmp/ksft-fchmodat2.XXXXXX";

	/* Make the top-level directory. */
	if (!mkdtemp(dirname))
		ksft_exit_fail_msg("%s: failed to create tmpdir\n", __func__);

	dfd = open(dirname, O_PATH | O_DIRECTORY);
	if (dfd < 0) {
		ksft_perror("failed to open tmpdir");
		goto err;
	}

	ret = openat(dfd, "regfile", O_CREAT | O_WRONLY | O_TRUNC, 0644);
	if (ret < 0) {
		ksft_perror("failed to create file in tmpdir");
		goto err;
	}
	close(ret);

	ret = symlinkat("regfile", dfd, "symlink");
	if (ret < 0) {
		ksft_perror("symlinkat() failed");
		goto err_regfile;
	}

	testdir->dirname = strdup(dirname);
	if (!testdir->dirname) {
		ksft_perror("Out of memory");
		goto err_symlink;
	}
	testdir->dfd = dfd;

	return;

err_symlink:
	unlinkat(testdir->dfd, "symlink", 0);
err_regfile:
	unlinkat(testdir->dfd, "regfile", 0);
err:
	unlink(dirname);
	ksft_exit_fail();
}

static void cleanup_testdir(struct testdir *testdir)
{
	unlinkat(testdir->dfd, "regfile", 0);
	unlinkat(testdir->dfd, "symlink", 0);
	rmdir(testdir->dirname);
	free(testdir->dirname);
}

int expect_mode(int dfd, const char *filename, mode_t expect_mode)
{
	struct stat st;
	int ret = fstatat(dfd, filename, &st, AT_SYMLINK_NOFOLLOW);

	if (ret) {
		ksft_perror("fstatat() failed\n");
		return 0;
	}

	return (st.st_mode == expect_mode);
}

void test_regfile(void)
{
	struct testdir testdir;
	int ret;

	setup_testdir(&testdir);

	ret = sys_fchmodat2(testdir.dfd, "regfile", 0640, 0);

	if (ret < 0) {
		ksft_perror("fchmodat2(noflag) failed");

Annotation

Implementation Notes