1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 6f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 7f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 8f08c3bdfSopenharmony_ci * (at your option) any later version. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 11f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 16f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 17f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci/* 21f08c3bdfSopenharmony_ci * Test Name: mknod06 22f08c3bdfSopenharmony_ci * 23f08c3bdfSopenharmony_ci * Test Description: 24f08c3bdfSopenharmony_ci * Verify that, 25f08c3bdfSopenharmony_ci * 1) mknod(2) returns -1 and sets errno to EEXIST if specified path 26f08c3bdfSopenharmony_ci * already exists. 27f08c3bdfSopenharmony_ci * 2) mknod(2) returns -1 and sets errno to EFAULT if pathname points 28f08c3bdfSopenharmony_ci * outside user's accessible address space. 29f08c3bdfSopenharmony_ci * 3) mknod(2) returns -1 and sets errno to ENOENT if the directory 30f08c3bdfSopenharmony_ci * component in pathname does not exist. 31f08c3bdfSopenharmony_ci * 4) mknod(2) returns -1 and sets errno to ENAMETOOLONG if the pathname 32f08c3bdfSopenharmony_ci * component was too long. 33f08c3bdfSopenharmony_ci * 5) mknod(2) returns -1 and sets errno to ENOTDIR if the directory 34f08c3bdfSopenharmony_ci * component in pathname is not a directory. 35f08c3bdfSopenharmony_ci * 36f08c3bdfSopenharmony_ci * Expected Result: 37f08c3bdfSopenharmony_ci * mknod() should fail with return value -1 and set expected errno. 38f08c3bdfSopenharmony_ci * 39f08c3bdfSopenharmony_ci * Algorithm: 40f08c3bdfSopenharmony_ci * Setup: 41f08c3bdfSopenharmony_ci * Setup signal handling. 42f08c3bdfSopenharmony_ci * Create temporary directory. 43f08c3bdfSopenharmony_ci * Pause for SIGUSR1 if option specified. 44f08c3bdfSopenharmony_ci * 45f08c3bdfSopenharmony_ci * Test: 46f08c3bdfSopenharmony_ci * Loop if the proper options are given. 47f08c3bdfSopenharmony_ci * Execute system call 48f08c3bdfSopenharmony_ci * Check return code, if system call failed (return=-1) 49f08c3bdfSopenharmony_ci * if errno set == expected errno 50f08c3bdfSopenharmony_ci * Issue sys call fails with expected return value and errno. 51f08c3bdfSopenharmony_ci * Otherwise, 52f08c3bdfSopenharmony_ci * Issue sys call fails with unexpected errno. 53f08c3bdfSopenharmony_ci * Otherwise, 54f08c3bdfSopenharmony_ci * Issue sys call returns unexpected value. 55f08c3bdfSopenharmony_ci * 56f08c3bdfSopenharmony_ci * Cleanup: 57f08c3bdfSopenharmony_ci * Print errno log and/or timing stats if options given 58f08c3bdfSopenharmony_ci * Delete the temporary directory(s)/file(s) created. 59f08c3bdfSopenharmony_ci * 60f08c3bdfSopenharmony_ci * Usage: <for command-line> 61f08c3bdfSopenharmony_ci * mknod06 [-c n] [-e] [-i n] [-I x] [-P x] [-t] 62f08c3bdfSopenharmony_ci * where, -c n : Run n copies concurrently. 63f08c3bdfSopenharmony_ci * -e : Turn on errno logging. 64f08c3bdfSopenharmony_ci * -i n : Execute test n times. 65f08c3bdfSopenharmony_ci * -I x : Execute test for x seconds. 66f08c3bdfSopenharmony_ci * -P x : Pause for x seconds between iterations. 67f08c3bdfSopenharmony_ci * -t : Turn on syscall timing. 68f08c3bdfSopenharmony_ci * 69f08c3bdfSopenharmony_ci * HISTORY 70f08c3bdfSopenharmony_ci * 07/2001 Ported by Wayne Boyer 71f08c3bdfSopenharmony_ci * 72f08c3bdfSopenharmony_ci * RESTRICTIONS: 73f08c3bdfSopenharmony_ci * This test should be executed by super-user (root) only. 74f08c3bdfSopenharmony_ci */ 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci#include <stdio.h> 77f08c3bdfSopenharmony_ci#include <stdlib.h> 78f08c3bdfSopenharmony_ci#include <unistd.h> 79f08c3bdfSopenharmony_ci#include <errno.h> 80f08c3bdfSopenharmony_ci#include <string.h> 81f08c3bdfSopenharmony_ci#include <signal.h> 82f08c3bdfSopenharmony_ci#include <sys/types.h> 83f08c3bdfSopenharmony_ci#include <sys/stat.h> 84f08c3bdfSopenharmony_ci#include <sys/param.h> 85f08c3bdfSopenharmony_ci#include <sys/mman.h> 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci#include "test.h" 88f08c3bdfSopenharmony_ci 89f08c3bdfSopenharmony_ci#define MODE_RWX S_IFIFO | S_IRWXU | S_IRWXG | S_IRWXO 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ciint setup1(); /* setup function to test mknod for EEXIST */ 92f08c3bdfSopenharmony_ciint setup3(); /* setup function to test mknod for ENOTDIR */ 93f08c3bdfSopenharmony_ciint longpath_setup(); /* setup function to test mknod for ENAMETOOLONG */ 94f08c3bdfSopenharmony_ciint no_setup(); /* simply returns 0 to the caller */ 95f08c3bdfSopenharmony_cichar Longpathname[PATH_MAX + 2]; 96f08c3bdfSopenharmony_ci 97f08c3bdfSopenharmony_cistruct test_case_t { /* test case struct. to hold ref. test cond's */ 98f08c3bdfSopenharmony_ci char *pathname; 99f08c3bdfSopenharmony_ci char *desc; 100f08c3bdfSopenharmony_ci int exp_errno; 101f08c3bdfSopenharmony_ci int (*setupfunc) (); 102f08c3bdfSopenharmony_ci} Test_cases[] = { 103f08c3bdfSopenharmony_ci {"tnode_1", "Specified node already exists", EEXIST, setup1}, { 104f08c3bdfSopenharmony_ci NULL, "Invalid address", EFAULT, no_setup}, { 105f08c3bdfSopenharmony_ci "testdir_2/tnode_2", "Non-existent file", ENOENT, no_setup}, { 106f08c3bdfSopenharmony_ci "", "Pathname is empty", ENOENT, no_setup}, { 107f08c3bdfSopenharmony_ci Longpathname, "Pathname too long", ENAMETOOLONG, longpath_setup}, { 108f08c3bdfSopenharmony_ci "tnode/tnode_3", "Path contains regular file", ENOTDIR, setup3}, { 109f08c3bdfSopenharmony_ci NULL, NULL, 0, no_setup} 110f08c3bdfSopenharmony_ci}; 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_cichar *TCID = "mknod06"; 113f08c3bdfSopenharmony_ciint TST_TOTAL = ARRAY_SIZE(Test_cases); 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_civoid setup(); /* setup function for the tests */ 116f08c3bdfSopenharmony_civoid cleanup(); /* cleanup function for the tests */ 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ciint main(int ac, char **av) 119f08c3bdfSopenharmony_ci{ 120f08c3bdfSopenharmony_ci int lc; 121f08c3bdfSopenharmony_ci char *node_name; /* ptr. for node name created */ 122f08c3bdfSopenharmony_ci char *test_desc; /* test specific error message */ 123f08c3bdfSopenharmony_ci int ind; /* counter to test different test conditions */ 124f08c3bdfSopenharmony_ci 125f08c3bdfSopenharmony_ci tst_parse_opts(ac, av, NULL, NULL); 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci /* 128f08c3bdfSopenharmony_ci * Invoke setup function to call individual test setup functions 129f08c3bdfSopenharmony_ci * for the test which run as root/super-user. 130f08c3bdfSopenharmony_ci */ 131f08c3bdfSopenharmony_ci setup(); 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); lc++) { 134f08c3bdfSopenharmony_ci 135f08c3bdfSopenharmony_ci tst_count = 0; 136f08c3bdfSopenharmony_ci 137f08c3bdfSopenharmony_ci for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 138f08c3bdfSopenharmony_ci node_name = Test_cases[ind].pathname; 139f08c3bdfSopenharmony_ci test_desc = Test_cases[ind].desc; 140f08c3bdfSopenharmony_ci 141f08c3bdfSopenharmony_ci /* 142f08c3bdfSopenharmony_ci * Call mknod(2) to test different test conditions. 143f08c3bdfSopenharmony_ci * verify that it fails with -1 return value and 144f08c3bdfSopenharmony_ci * sets appropriate errno. 145f08c3bdfSopenharmony_ci */ 146f08c3bdfSopenharmony_ci TEST(mknod(node_name, MODE_RWX, 0)); 147f08c3bdfSopenharmony_ci 148f08c3bdfSopenharmony_ci /* Check return code from mknod(2) */ 149f08c3bdfSopenharmony_ci if (TEST_RETURN != -1) { 150f08c3bdfSopenharmony_ci tst_resm(TFAIL, 151f08c3bdfSopenharmony_ci "mknod() returned %ld, expected " 152f08c3bdfSopenharmony_ci "-1, errno:%d", TEST_RETURN, 153f08c3bdfSopenharmony_ci Test_cases[ind].exp_errno); 154f08c3bdfSopenharmony_ci continue; 155f08c3bdfSopenharmony_ci } 156f08c3bdfSopenharmony_ci 157f08c3bdfSopenharmony_ci if (TEST_ERRNO == Test_cases[ind].exp_errno) { 158f08c3bdfSopenharmony_ci tst_resm(TPASS, "mknod() fails, %s, errno:%d", 159f08c3bdfSopenharmony_ci test_desc, TEST_ERRNO); 160f08c3bdfSopenharmony_ci } else { 161f08c3bdfSopenharmony_ci tst_resm(TFAIL, "mknod() fails, %s, errno:%d, " 162f08c3bdfSopenharmony_ci "expected errno:%d", test_desc, 163f08c3bdfSopenharmony_ci TEST_ERRNO, Test_cases[ind].exp_errno); 164f08c3bdfSopenharmony_ci } 165f08c3bdfSopenharmony_ci } 166f08c3bdfSopenharmony_ci 167f08c3bdfSopenharmony_ci } 168f08c3bdfSopenharmony_ci 169f08c3bdfSopenharmony_ci /* 170f08c3bdfSopenharmony_ci * Invoke cleanup() to delete the test directories created 171f08c3bdfSopenharmony_ci * in the setup(). 172f08c3bdfSopenharmony_ci */ 173f08c3bdfSopenharmony_ci cleanup(); 174f08c3bdfSopenharmony_ci 175f08c3bdfSopenharmony_ci tst_exit(); 176f08c3bdfSopenharmony_ci} 177f08c3bdfSopenharmony_ci 178f08c3bdfSopenharmony_ci/* 179f08c3bdfSopenharmony_ci * setup(void) - performs all ONE TIME setup for this test. 180f08c3bdfSopenharmony_ci * Exit the test program on receipt of unexpected signals. 181f08c3bdfSopenharmony_ci * Create a temporary directory used to hold test directories and nodes 182f08c3bdfSopenharmony_ci * created and change the directory to it. 183f08c3bdfSopenharmony_ci * Invoke individual test setup functions according to the order 184f08c3bdfSopenharmony_ci * set in struct. definition. 185f08c3bdfSopenharmony_ci */ 186f08c3bdfSopenharmony_civoid setup(void) 187f08c3bdfSopenharmony_ci{ 188f08c3bdfSopenharmony_ci int ind; 189f08c3bdfSopenharmony_ci 190f08c3bdfSopenharmony_ci tst_require_root(); 191f08c3bdfSopenharmony_ci 192f08c3bdfSopenharmony_ci /* Capture unexpected signals */ 193f08c3bdfSopenharmony_ci tst_sig(NOFORK, DEF_HANDLER, cleanup); 194f08c3bdfSopenharmony_ci 195f08c3bdfSopenharmony_ci TEST_PAUSE; 196f08c3bdfSopenharmony_ci 197f08c3bdfSopenharmony_ci /* Make a temp dir and cd to it */ 198f08c3bdfSopenharmony_ci tst_tmpdir(); 199f08c3bdfSopenharmony_ci 200f08c3bdfSopenharmony_ci /* call individual setup functions */ 201f08c3bdfSopenharmony_ci for (ind = 0; Test_cases[ind].desc != NULL; ind++) { 202f08c3bdfSopenharmony_ci if (!Test_cases[ind].pathname) 203f08c3bdfSopenharmony_ci Test_cases[ind].pathname = tst_get_bad_addr(cleanup); 204f08c3bdfSopenharmony_ci Test_cases[ind].setupfunc(); 205f08c3bdfSopenharmony_ci } 206f08c3bdfSopenharmony_ci} 207f08c3bdfSopenharmony_ci 208f08c3bdfSopenharmony_ci/* 209f08c3bdfSopenharmony_ci * no_setup() - Some test conditions for mknod(2) do not any setup. 210f08c3bdfSopenharmony_ci * Hence, this function just returns 0. 211f08c3bdfSopenharmony_ci */ 212f08c3bdfSopenharmony_ciint no_setup(void) 213f08c3bdfSopenharmony_ci{ 214f08c3bdfSopenharmony_ci return 0; 215f08c3bdfSopenharmony_ci} 216f08c3bdfSopenharmony_ci 217f08c3bdfSopenharmony_ci/* 218f08c3bdfSopenharmony_ci * longpath_setup() - setup to create a node with a name length exceeding 219f08c3bdfSopenharmony_ci * the MAX. length of PATH_MAX. 220f08c3bdfSopenharmony_ci * This function retruns 0. 221f08c3bdfSopenharmony_ci */ 222f08c3bdfSopenharmony_ciint longpath_setup(void) 223f08c3bdfSopenharmony_ci{ 224f08c3bdfSopenharmony_ci int ind; /* counter variable */ 225f08c3bdfSopenharmony_ci 226f08c3bdfSopenharmony_ci for (ind = 0; ind <= (PATH_MAX + 1); ind++) { 227f08c3bdfSopenharmony_ci Longpathname[ind] = 'a'; 228f08c3bdfSopenharmony_ci } 229f08c3bdfSopenharmony_ci return 0; 230f08c3bdfSopenharmony_ci} 231f08c3bdfSopenharmony_ci 232f08c3bdfSopenharmony_ci/* 233f08c3bdfSopenharmony_ci * setup1() - setup function for a test condition for which mknod(2) 234f08c3bdfSopenharmony_ci * returns -1 and sets errno to EEXIST. 235f08c3bdfSopenharmony_ci * This function creates a node using mknod(2) and tries to create 236f08c3bdfSopenharmony_ci * same node in the test and fails with above errno. 237f08c3bdfSopenharmony_ci * This function returns 0. 238f08c3bdfSopenharmony_ci */ 239f08c3bdfSopenharmony_ciint setup1(void) 240f08c3bdfSopenharmony_ci{ 241f08c3bdfSopenharmony_ci /* Create a node using mknod */ 242f08c3bdfSopenharmony_ci if (mknod("tnode_1", MODE_RWX, 0) < 0) { 243f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "Fails to create node in setup1()"); 244f08c3bdfSopenharmony_ci } 245f08c3bdfSopenharmony_ci 246f08c3bdfSopenharmony_ci return 0; 247f08c3bdfSopenharmony_ci} 248f08c3bdfSopenharmony_ci 249f08c3bdfSopenharmony_ci/* 250f08c3bdfSopenharmony_ci * setup3() - setup function for a test condition for which mknod(2) 251f08c3bdfSopenharmony_ci * returns -1 and sets errno to ENOTDIR. 252f08c3bdfSopenharmony_ci * This function creates a node under temporary directory and the 253f08c3bdfSopenharmony_ci * test attempts to create another node under under this node and fails 254f08c3bdfSopenharmony_ci * with ENOTDIR as the node created here is a regular file. 255f08c3bdfSopenharmony_ci * This function returns 0. 256f08c3bdfSopenharmony_ci */ 257f08c3bdfSopenharmony_ciint setup3(void) 258f08c3bdfSopenharmony_ci{ 259f08c3bdfSopenharmony_ci /* Create a node using mknod */ 260f08c3bdfSopenharmony_ci if (mknod("tnode", MODE_RWX, 0) < 0) { 261f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "Fails to create node in setup3()"); 262f08c3bdfSopenharmony_ci } 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci return 0; 265f08c3bdfSopenharmony_ci} 266f08c3bdfSopenharmony_ci 267f08c3bdfSopenharmony_ci/* 268f08c3bdfSopenharmony_ci * cleanup() - Performs all ONE TIME cleanup for this test at 269f08c3bdfSopenharmony_ci * completion or premature exit. 270f08c3bdfSopenharmony_ci * Print test timing stats and errno log if test executed with options. 271f08c3bdfSopenharmony_ci * Remove temporary directory and sub-directories/files under it 272f08c3bdfSopenharmony_ci * created during setup(). 273f08c3bdfSopenharmony_ci * Exit the test program with normal exit code. 274f08c3bdfSopenharmony_ci */ 275f08c3bdfSopenharmony_civoid cleanup(void) 276f08c3bdfSopenharmony_ci{ 277f08c3bdfSopenharmony_ci 278f08c3bdfSopenharmony_ci tst_rmdir(); 279f08c3bdfSopenharmony_ci 280f08c3bdfSopenharmony_ci} 281