tools/testing/selftests/filesystems/openat2/resolve_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/filesystems/openat2/resolve_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/filesystems/openat2/resolve_test.c
Extension
.c
Size
22738 bytes
Lines
562
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 resolve_test {
	const char *name;
	const char *dir;
	const char *path;
	struct open_how how;
	bool pass;
	union {
		int err;
		const char *path;
	} out;
};

/*
 * Verify a single resolve test case. This must be called from within a TEST_F
 * function with _metadata in scope.
 */
static void verify_resolve_test(struct __test_metadata *_metadata,
				int rootfd, int hardcoded_fd,
				const struct resolve_test *test)
{
	struct open_how how = test->how;
	int dfd, fd;
	char *fdpath = NULL;

	/* Auto-set O_PATH. */
	if (!(how.flags & O_CREAT))
		how.flags |= O_PATH;

	if (test->dir)
		dfd = openat(rootfd, test->dir, O_PATH | O_DIRECTORY);
	else
		dfd = dup(rootfd);
	ASSERT_GE(dfd, 0) TH_LOG("failed to open dir '%s': %m", test->dir ?: ".");
	ASSERT_EQ(dup2(dfd, hardcoded_fd), hardcoded_fd);

	fd = sys_openat2(dfd, test->path, &how);

	if (test->pass) {
		EXPECT_GE(fd, 0) {
			TH_LOG("%s: expected success, got %d (%s)",
			       test->name, fd, strerror(-fd));
		}
		if (fd >= 0) {
			EXPECT_TRUE(fdequal(_metadata, fd, rootfd, test->out.path)) {
				fdpath = fdreadlink(_metadata, fd);
				TH_LOG("%s: wrong path '%s', expected '%s'",
				       test->name, fdpath,
				       test->out.path ?: ".");
				free(fdpath);
			}
		}
	} else {
		EXPECT_EQ(test->out.err, fd) {
			if (fd >= 0) {
				fdpath = fdreadlink(_metadata, fd);
				TH_LOG("%s: expected %d (%s), got %d['%s']",
				       test->name, test->out.err,
				       strerror(-test->out.err), fd, fdpath);
				free(fdpath);
			} else {
				TH_LOG("%s: expected %d (%s), got %d (%s)",
				       test->name, test->out.err,
				       strerror(-test->out.err),
				       fd, strerror(-fd));
			}
		}
	}

	if (fd >= 0)
		close(fd);
	close(dfd);
}

/*
 * Construct a test directory with the following structure:
 *
 * root/
 * |-- procexe -> /proc/self/exe
 * |-- procroot -> /proc/self/root
 * |-- root/
 * |-- mnt/ [mountpoint]
 * |   |-- self -> ../mnt/
 * |   `-- absself -> /mnt/
 * |-- etc/
 * |   `-- passwd
 * |-- creatlink -> /newfile3
 * |-- reletc -> etc/
 * |-- relsym -> etc/passwd
 * |-- absetc -> /etc/
 * |-- abssym -> /etc/passwd

Annotation

Implementation Notes