1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) International Business Machines Corp., 2001 4 * Ported to LTP: Wayne Boyer 5 */ 6 7/* 8 * Test Description : 9 * Testcase to check the basic functionality of the readlink(2), 10 * readlink() will succeed to read the contents of the symbolic link. 11 */ 12 13#include <pwd.h> 14#include <errno.h> 15#include <string.h> 16 17#include "tst_test.h" 18 19#define TESTFILE "test_file" 20#define SYMFILE "slink_file" 21 22static uid_t nobody_uid; 23 24static void test_readlink(void) 25{ 26 char buffer[256]; 27 int exp_val = strlen(TESTFILE); 28 29 TEST(readlink(SYMFILE, buffer, sizeof(buffer))); 30 if (TST_RET == -1) { 31 tst_res(TFAIL | TTERRNO, "readlink() on %s failed", SYMFILE); 32 return; 33 } 34 35 if (TST_RET != exp_val) { 36 tst_res(TFAIL, "readlink() returned value %ld " 37 "did't match, Expected %d", TST_RET, exp_val); 38 return; 39 } 40 41 if (memcmp(buffer, TESTFILE, exp_val) != 0) { 42 tst_res(TFAIL, "Pathname %s and buffer contents %s differ", 43 TESTFILE, buffer); 44 } else { 45 tst_res(TPASS, "readlink() functionality on '%s' was correct", 46 SYMFILE); 47 } 48} 49 50static void verify_readlink(unsigned int n) 51{ 52 pid_t pid; 53 54 if (n) { 55 tst_res(TINFO, "Running test as nobody"); 56 pid = SAFE_FORK(); 57 58 if (!pid) { 59 SAFE_SETUID(nobody_uid); 60 test_readlink(); 61 return; 62 } 63 } else { 64 tst_res(TINFO, "Running test as root"); 65 test_readlink(); 66 } 67} 68 69static void setup(void) 70{ 71 int fd; 72 struct passwd *pw; 73 74 pw = SAFE_GETPWNAM("nobody"); 75 76 nobody_uid = pw->pw_uid; 77 78 fd = SAFE_OPEN(TESTFILE, O_RDWR | O_CREAT, 0444); 79 SAFE_CLOSE(fd); 80 SAFE_SYMLINK(TESTFILE, SYMFILE); 81} 82 83static struct tst_test test = { 84 .test = verify_readlink,\ 85 .tcnt = 2, 86 .setup = setup, 87 .forks_child = 1, 88 .needs_root = 1, 89 .needs_tmpdir = 1, 90}; 91