1/****************************************************************************** 2 * 3 * Copyright (c) International Business Machines Corp., 2006 4 * Author: Yi Yang <yyangcdl@cn.ibm.com> 5 * Copyright (c) Cyril Hrubis 2014 <chrubis@suse.cz> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 15 * the GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/* 23 * DESCRIPTION 24 * This test case will verify basic function of mkdirat 25 * added by kernel 2.6.16 or up. 26 */ 27 28#define _GNU_SOURCE 29 30#include <sys/types.h> 31#include <sys/stat.h> 32#include <fcntl.h> 33#include <stdlib.h> 34#include <errno.h> 35#include <string.h> 36#include <signal.h> 37#include "test.h" 38#include "lapi/mkdirat.h" 39#include "safe_macros.h" 40 41static void setup(void); 42static void cleanup(void); 43 44static char relpath[256]; 45static char abspath[1024]; 46static int dir_fd, fd; 47static int fd_invalid = 100; 48static int fd_atcwd = AT_FDCWD; 49 50static struct test_case { 51 int *dir_fd; 52 const char *name; 53 int exp_ret; 54 int exp_errno; 55} test_cases[] = { 56 {&dir_fd, relpath, 0, 0}, 57 {&dir_fd, abspath, 0, 0}, 58 {&fd_atcwd, relpath, 0, 0}, 59 {&fd, relpath, -1, ENOTDIR}, 60 {&fd_invalid, relpath, -1, EBADF}, 61}; 62 63char *TCID = "mkdirat01"; 64int TST_TOTAL = ARRAY_SIZE(test_cases); 65 66static void verify_mkdirat(struct test_case *test) 67{ 68 TEST(mkdirat(*test->dir_fd, test->name, 0600)); 69 70 if (TEST_RETURN != test->exp_ret) { 71 tst_resm(TFAIL | TTERRNO, 72 "mkdirat() returned %ld, expected %d", 73 TEST_RETURN, test->exp_ret); 74 return; 75 } 76 77 if (TEST_ERRNO != test->exp_errno) { 78 tst_resm(TFAIL | TTERRNO, 79 "mkdirat() returned wrong errno, expected %d", 80 test->exp_errno); 81 return; 82 } 83 84 tst_resm(TPASS | TTERRNO, "mkdirat() returned %ld", TEST_RETURN); 85} 86 87static void setup_iteration(int i) 88{ 89 static char testdir[256]; 90 char *tmpdir = tst_get_tmpdir(); 91 92 /* Initialize test dir and file names */ 93 sprintf(testdir, "mkdirattestdir%d_%d", getpid(), i); 94 sprintf(relpath, "mkdiratrelpath%d_%d", getpid(), i); 95 sprintf(abspath, "%s/mkdiratrelpath%d_%d_2", tmpdir, getpid(), i); 96 97 free(tmpdir); 98 99 SAFE_MKDIR(cleanup, testdir, 0700); 100 dir_fd = SAFE_OPEN(cleanup, testdir, O_DIRECTORY); 101} 102 103static void cleanup_iteration(void) 104{ 105 SAFE_CLOSE(cleanup, dir_fd); 106} 107 108int main(int ac, char **av) 109{ 110 int lc; 111 int i; 112 113 tst_parse_opts(ac, av, NULL, NULL); 114 115 setup(); 116 117 for (lc = 0; TEST_LOOPING(lc); lc++) { 118 tst_count = 0; 119 120 setup_iteration(lc); 121 122 for (i = 0; i < TST_TOTAL; i++) 123 verify_mkdirat(test_cases + i); 124 125 cleanup_iteration(); 126 } 127 128 cleanup(); 129 tst_exit(); 130} 131 132static void setup(void) 133{ 134 TEST_PAUSE; 135 tst_tmpdir(); 136 137 fd = SAFE_OPEN(cleanup, "mkdirattestfile", O_CREAT | O_RDWR, 0600); 138} 139 140static void cleanup(void) 141{ 142 if (fd > 0) 143 close(fd); 144 145 tst_rmdir(); 146} 147