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