Home | History | Annotate | Download | only in readdir
      1 /*
      2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
      3  *
      4  * This program is free software; you can redistribute it and/or modify it
      5  * under the terms of version 2 of the GNU General Public License as
      6  * published by the Free Software Foundation.
      7  *
      8  * This program is distributed in the hope that it would be useful, but
      9  * WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     11  *
     12  * Further, this software is distributed without any warranty that it is
     13  * free of the rightful claim of any third person regarding infringement
     14  * or the like.  Any license provided herein, whether implied or
     15  * otherwise, applies only to this software file.  Patent licenses, if
     16  * any, provided herein do not apply to combinations of this program with
     17  * other software, or any other product whatsoever.
     18  *
     19  * You should have received a copy of the GNU General Public License along
     20  * with this program; if not, write the Free Software Foundation, Inc.,
     21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     22  *
     23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
     24  * Mountain View, CA  94043, or:
     25  *
     26  * http://www.sgi.com
     27  *
     28  * For further information regarding this notice, see:
     29  *
     30  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
     31  *
     32  */
     33 /* $Id: readdir01.c,v 1.7 2009/03/23 13:36:01 subrata_modak Exp $ */
     34 /**********************************************************
     35  *
     36  *    OS Test - Silicon Graphics, Inc.
     37  *
     38  *    TEST IDENTIFIER	: readdir01
     39  *
     40  *    EXECUTED BY	: anyone
     41  *
     42  *    TEST TITLE	: write multiple files and try to find them with readdir
     43  *
     44  *    TEST CASE TOTAL	:
     45  *
     46  *    WALL CLOCK TIME	:
     47  *
     48  *    CPU TYPES		: ALL
     49  *
     50  *    AUTHOR		: Nate Straz
     51  *
     52  *    CO-PILOT		:
     53  *
     54  *    DATE STARTED	: 02/16/2001
     55  *
     56  *    INITIAL RELEASE	: Linux 2.4.x
     57  *
     58  *    TEST CASES
     59  *
     60  * 	1.) Create n files and check that readdir() finds n files
     61  *
     62  *    INPUT SPECIFICATIONS
     63  * 	The standard options for system call tests are accepted.
     64  *	(See the parse_opts(3) man page).
     65  *
     66  *    OUTPUT SPECIFICATIONS
     67  *$
     68  *    DURATION
     69  * 	Terminates - with frequency and infinite modes.
     70  *
     71  *    SIGNALS
     72  * 	Uses SIGUSR1 to pause before test if option set.
     73  * 	(See the parse_opts(3) man page).
     74  *
     75  *    RESOURCES
     76  * 	None
     77  *
     78  *    ENVIRONMENTAL NEEDS
     79  *      No run-time environmental needs.
     80  *
     81  *    SPECIAL PROCEDURAL REQUIREMENTS
     82  * 	None
     83  *
     84  *    INTERCASE DEPENDENCIES
     85  * 	None
     86  *
     87  *    DETAILED DESCRIPTION
     88  *	This is a Phase I test for the readdir(2) system call.  It is intended
     89  *	to provide a limited exposure of the system call, for now.  It
     90  *	should/will be extended when full functional tests are written for
     91  *	readdir(2).
     92  *
     93  * 	Setup:
     94  * 	  Setup signal handling.
     95  *	  Pause for SIGUSR1 if option specified.
     96  *
     97  * 	Test:
     98  *	 Loop if the proper options are given.
     99  * 	  Execute system call
    100  *	  Check return code, if system call failed (return=-1)
    101  *		Log the errno and Issue a FAIL message.
    102  *	  Otherwise, Issue a PASS message.
    103  *
    104  * 	Cleanup:
    105  * 	  Print errno log and/or timing stats if options given
    106  *
    107  *
    108  *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
    109 
    110 #include <sys/types.h>
    111 #include <sys/stat.h>
    112 #include <fcntl.h>
    113 #include <dirent.h>
    114 #include <unistd.h>
    115 #include <errno.h>
    116 #include <string.h>
    117 #include <signal.h>
    118 #include "test.h"
    119 
    120  /* The setup and cleanup functions are basic parts of a test case.  These
    121   * steps are usually put in separate functions for clarity.  The help function
    122   * is only needed when you are adding new command line options.
    123   */
    124 void setup();
    125 void help();
    126 void cleanup();
    127 
    128 char *TCID = "readdir01";
    129 int TST_TOTAL = 2;
    130 
    131 #define BASENAME	"readdirfile"
    132 
    133 char Basename[255];
    134 char Fname[255];
    135 int Nfiles = 0;
    136 
    137 char *Nfilearg;
    138 int Nflag = 0;
    139 
    140 option_t options[] = {
    141 	{"N:", &Nflag, &Nfilearg},	/* -N #files */
    142 	{NULL, NULL, NULL}
    143 };
    144 
    145 /***********************************************************************
    146  * Main
    147  ***********************************************************************/
    148 int main(int ac, char **av)
    149 {
    150 	int lc;
    151 	int cnt;
    152 	int nfiles, fd;
    153 	char fname[255];
    154 	DIR *test_dir;
    155 	struct dirent *dptr;
    156 
    157 	tst_parse_opts(ac, av, options, &help);
    158 
    159 	if (Nflag) {
    160 		if (sscanf(Nfilearg, "%i", &Nfiles) != 1) {
    161 			tst_brkm(TBROK, NULL, "--N option arg is not a number");
    162 		}
    163 	}
    164 
    165     /***************************************************************
    166      * perform global setup for test
    167      ***************************************************************/
    168 	/* Next you should run a setup routine to make sure your environment is
    169 	 * sane.
    170 	 */
    171 	setup();
    172 
    173     /***************************************************************
    174      * check looping state
    175      ***************************************************************/
    176 	/* TEST_LOOPING() is a macro that will make sure the test continues
    177 	 * looping according to the standard command line args.
    178 	 */
    179 	for (lc = 0; TEST_LOOPING(lc); lc++) {
    180 
    181 		tst_count = 0;
    182 
    183 		if (Nfiles)
    184 			nfiles = Nfiles;
    185 		else
    186 			/* min of 10 links and max of a 100 links */
    187 			nfiles = (lc % 90) + 10;
    188 
    189 		/* create a bunch of files to look at */
    190 		for (cnt = 0; cnt < nfiles; cnt++) {
    191 
    192 			sprintf(fname, "%s%d", Basename, cnt);
    193 			if ((fd = open(fname, O_RDWR | O_CREAT, 0700)) == -1) {
    194 				tst_brkm(TBROK, cleanup,
    195 					 "open(%s, O_RDWR|O_CREAT,0700) Failed, errno=%d : %s",
    196 					 fname, errno, strerror(errno));
    197 			} else if (write(fd, "hello\n", 6) < 0) {
    198 				tst_brkm(TBROK, cleanup,
    199 					 "write(%s, \"hello\\n\", 6) Failed, errno=%d : %s",
    200 					 fname, errno, strerror(errno));
    201 			} else if (close(fd) < 0) {
    202 				tst_resm(TWARN,
    203 					"close(%s) Failed, errno=%d : %s",
    204 					fname, errno, strerror(errno));
    205 			}
    206 		}
    207 
    208 		if ((test_dir = opendir(".")) == NULL) {
    209 			tst_resm(TFAIL, "opendir(\".\") Failed, errno=%d : %s",
    210 				 errno, strerror(errno));
    211 		} else {
    212 			/* count the entries we find to see if any are missing */
    213 			cnt = 0;
    214 			errno = 0;
    215 			while ((dptr = readdir(test_dir)) != 0) {
    216 				if (strcmp(dptr->d_name, ".")
    217 				    && strcmp(dptr->d_name, ".."))
    218 					cnt++;
    219 			}
    220 
    221 			if (errno != 0) {
    222 				tst_resm(TFAIL,
    223 					 "readir(test_dir) Failed on try %d, errno=%d : %s",
    224 					 cnt + 1, errno, strerror(errno));
    225 			}
    226 			if (cnt == nfiles) {
    227 				tst_resm(TPASS,
    228 					 "found all %d that were created",
    229 					 nfiles);
    230 			} else if (cnt > nfiles) {
    231 				tst_resm(TFAIL,
    232 					 "found more files than were created");
    233 				tst_resm(TINFO, "created: %d, found: %d",
    234 					 nfiles, cnt);
    235 			} else {
    236 				tst_resm(TFAIL,
    237 					 "found less files than were created");
    238 				tst_resm(TINFO, "created: %d, found: %d",
    239 					 nfiles, cnt);
    240 			}
    241 		}
    242 
    243 		/* Here we clean up after the test case so we can do another iteration.
    244 		 */
    245 		for (cnt = 0; cnt < nfiles; cnt++) {
    246 
    247 			sprintf(fname, "%s%d", Basename, cnt);
    248 
    249 			if (unlink(fname) == -1) {
    250 				tst_resm(TWARN,
    251 					"unlink(%s) Failed, errno=%d : %s",
    252 					Fname, errno, strerror(errno));
    253 			}
    254 		}
    255 
    256 	}
    257 
    258     /***************************************************************
    259      * cleanup and exit
    260      ***************************************************************/
    261 	cleanup();
    262 
    263 	tst_exit();
    264 }
    265 
    266 /***************************************************************
    267  * help
    268  ***************************************************************/
    269 /* The custom help() function is really simple.  Just write your help message to
    270  * standard out.  Your help function will be called after the standard options
    271  * have been printed
    272  */
    273 void help(void)
    274 {
    275 	printf("  -N #files : create #files files every iteration\n");
    276 }
    277 
    278 /***************************************************************
    279  * setup() - performs all ONE TIME setup for this test.
    280  ***************************************************************/
    281 void setup(void)
    282 {
    283 	/* You will want to enable some signal handling so you can capture
    284 	 * unexpected signals like SIGSEGV.
    285 	 */
    286 	tst_sig(NOFORK, DEF_HANDLER, cleanup);
    287 
    288 	/* One cavet that hasn't been fixed yet.  TEST_PAUSE contains the code to
    289 	 * fork the test with the -c option.  You want to make sure you do this
    290 	 * before you create your temporary directory.
    291 	 */
    292 	TEST_PAUSE;
    293 
    294 	/* If you are doing any file work, you should use a temporary directory.  We
    295 	 * provide tst_tmpdir() which will create a uniquely named temporary
    296 	 * directory and cd into it.  You can now create files in the current
    297 	 * directory without worrying.
    298 	 */
    299 	tst_tmpdir();
    300 
    301 	sprintf(Basename, "%s_%d.", BASENAME, getpid());
    302 }
    303 
    304 /***************************************************************
    305  * cleanup() - performs all ONE TIME cleanup for this test at
    306  *		completion or premature exit.
    307  ***************************************************************/
    308 void cleanup(void)
    309 {
    310 
    311 	/* If you use a temporary directory, you need to be sure you remove it. Use
    312 	 * tst_rmdir() to do it automatically.$
    313 	 */
    314 	tst_rmdir();
    315 
    316 }
    317