1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) Zilogic Systems Pvt. Ltd., 2018 4f08c3bdfSopenharmony_ci * Email: code@zilogic.com 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci 7f08c3bdfSopenharmony_ci/*\ 8f08c3bdfSopenharmony_ci * [Description] 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * This code tests the following flags with statx syscall: 11f08c3bdfSopenharmony_ci * 12f08c3bdfSopenharmony_ci * - AT_EMPTY_PATH 13f08c3bdfSopenharmony_ci * - AT_SYMLINK_NOFOLLOW 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * A test file and a link for it is created. 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * To check empty path flag, test file fd alone is passed. 18f08c3bdfSopenharmony_ci * Predefined size of testfile is checked against obtained value. 19f08c3bdfSopenharmony_ci * 20f08c3bdfSopenharmony_ci * To check symlink no follow flag, the linkname is statxed. 21f08c3bdfSopenharmony_ci * To ensure that link is not dereferenced, obtained inode is compared 22f08c3bdfSopenharmony_ci * with test file inode. 23f08c3bdfSopenharmony_ci */ 24f08c3bdfSopenharmony_ci 25f08c3bdfSopenharmony_ci#define _GNU_SOURCE 26f08c3bdfSopenharmony_ci#include <stdio.h> 27f08c3bdfSopenharmony_ci#include <inttypes.h> 28f08c3bdfSopenharmony_ci#include "tst_test.h" 29f08c3bdfSopenharmony_ci#include "tst_safe_macros.h" 30f08c3bdfSopenharmony_ci#include "lapi/stat.h" 31f08c3bdfSopenharmony_ci#include "lapi/fcntl.h" 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci#define TESTFILE "test_temp" 34f08c3bdfSopenharmony_ci#define LINK_FILE "test_temp_ln" 35f08c3bdfSopenharmony_ci#define MODE 0644 36f08c3bdfSopenharmony_ci#define SIZE 14 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_cistatic int file_fd; 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_cistatic void test_empty_path(void) 41f08c3bdfSopenharmony_ci{ 42f08c3bdfSopenharmony_ci struct statx buf; 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci TEST(statx(file_fd, "", AT_EMPTY_PATH, 0, &buf)); 45f08c3bdfSopenharmony_ci if (TST_RET == 0) 46f08c3bdfSopenharmony_ci tst_res(TPASS, 47f08c3bdfSopenharmony_ci "statx(file_fd, \"\", AT_EMPTY_PATH, 0, &buf)"); 48f08c3bdfSopenharmony_ci else 49f08c3bdfSopenharmony_ci tst_brk(TFAIL | TTERRNO, 50f08c3bdfSopenharmony_ci "statx(file_fd, \"\", AT_EMPTY_PATH, 0, &buff)"); 51f08c3bdfSopenharmony_ci 52f08c3bdfSopenharmony_ci if (buf.stx_size == SIZE) 53f08c3bdfSopenharmony_ci tst_res(TPASS, 54f08c3bdfSopenharmony_ci "stx_size(%"PRIu64") is correct", (uint64_t)buf.stx_size); 55f08c3bdfSopenharmony_ci else 56f08c3bdfSopenharmony_ci tst_res(TFAIL, 57f08c3bdfSopenharmony_ci "stx_size(%"PRIu64") is not same as expected(%u)", 58f08c3bdfSopenharmony_ci (uint64_t)buf.stx_size, SIZE); 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ci} 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_cistatic void test_sym_link(void) 63f08c3bdfSopenharmony_ci{ 64f08c3bdfSopenharmony_ci struct statx fbuf; 65f08c3bdfSopenharmony_ci struct statx lbuf; 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_ci TEST(statx(AT_FDCWD, TESTFILE, 0, 0, &fbuf)); 68f08c3bdfSopenharmony_ci 69f08c3bdfSopenharmony_ci if (TST_RET == 0) 70f08c3bdfSopenharmony_ci tst_res(TPASS, 71f08c3bdfSopenharmony_ci "statx(AT_FDCWD, %s, 0, 0, &fbuf)", TESTFILE); 72f08c3bdfSopenharmony_ci else 73f08c3bdfSopenharmony_ci tst_brk(TFAIL | TTERRNO, 74f08c3bdfSopenharmony_ci "statx(AT_FDCWD, %s, 0, 0, &fbuf)", TESTFILE); 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci TEST(statx(AT_FDCWD, LINK_FILE, AT_SYMLINK_NOFOLLOW, 0, &lbuf)); 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ci if (TST_RET == 0) 79f08c3bdfSopenharmony_ci tst_res(TPASS, 80f08c3bdfSopenharmony_ci "statx(AT_FDCWD, %s, AT_SYMLINK_NOFOLLOW, 0,&lbuf)", 81f08c3bdfSopenharmony_ci LINK_FILE); 82f08c3bdfSopenharmony_ci else 83f08c3bdfSopenharmony_ci tst_brk(TFAIL | TTERRNO, 84f08c3bdfSopenharmony_ci "statx(AT_FDCWD, %s, AT_SYMLINK_NOFOLLOW, 0,&lbuf)", 85f08c3bdfSopenharmony_ci LINK_FILE); 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci if (fbuf.stx_ino != lbuf.stx_ino) 88f08c3bdfSopenharmony_ci tst_res(TPASS, "Statx symlink flag worked as expected"); 89f08c3bdfSopenharmony_ci else 90f08c3bdfSopenharmony_ci tst_res(TFAIL, 91f08c3bdfSopenharmony_ci "Statx symlink flag failed to work as expected"); 92f08c3bdfSopenharmony_ci} 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_cistatic struct tcase { 95f08c3bdfSopenharmony_ci void (*tfunc)(void); 96f08c3bdfSopenharmony_ci} tcases[] = { 97f08c3bdfSopenharmony_ci {&test_empty_path}, 98f08c3bdfSopenharmony_ci {&test_sym_link} 99f08c3bdfSopenharmony_ci}; 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_cistatic void run(unsigned int i) 102f08c3bdfSopenharmony_ci{ 103f08c3bdfSopenharmony_ci tcases[i].tfunc(); 104f08c3bdfSopenharmony_ci} 105f08c3bdfSopenharmony_ci 106f08c3bdfSopenharmony_cistatic void setup(void) 107f08c3bdfSopenharmony_ci{ 108f08c3bdfSopenharmony_ci char data_buf[SIZE] = "LinusTorvalds"; 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci file_fd = SAFE_OPEN(TESTFILE, O_RDWR | O_CREAT, MODE); 111f08c3bdfSopenharmony_ci SAFE_WRITE(SAFE_WRITE_ANY, file_fd, data_buf, sizeof(data_buf)); 112f08c3bdfSopenharmony_ci 113f08c3bdfSopenharmony_ci SAFE_SYMLINK(TESTFILE, LINK_FILE); 114f08c3bdfSopenharmony_ci} 115f08c3bdfSopenharmony_ci 116f08c3bdfSopenharmony_cistatic void cleanup(void) 117f08c3bdfSopenharmony_ci{ 118f08c3bdfSopenharmony_ci if (file_fd > 0) 119f08c3bdfSopenharmony_ci SAFE_CLOSE(file_fd); 120f08c3bdfSopenharmony_ci} 121f08c3bdfSopenharmony_ci 122f08c3bdfSopenharmony_cistatic struct tst_test test = { 123f08c3bdfSopenharmony_ci .test = run, 124f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcases), 125f08c3bdfSopenharmony_ci .setup = setup, 126f08c3bdfSopenharmony_ci .cleanup = cleanup, 127f08c3bdfSopenharmony_ci .min_kver = "4.11", 128f08c3bdfSopenharmony_ci .needs_tmpdir = 1, 129f08c3bdfSopenharmony_ci}; 130