blob: 9f60494a2667508e8798650f708b574d18eb5cc8 [file] [log] [blame]
nstraz090ed002000-08-04 20:48:22 +00001/*
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., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, 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 */
nstraz94181082000-08-30 18:43:38 +000033/* $Id: link03.c,v 1.2 2000/08/30 18:43:38 nstraz Exp $ */
nstraz090ed002000-08-04 20:48:22 +000034/**********************************************************
35 *
36 * OS Test - Silicon Graphics, Inc.
37 *
38 * TEST IDENTIFIER : link03
39 *
40 * EXECUTED BY : anyone
41 *
42 * TEST TITLE : multi links tests
43 *
44 * PARENT DOCUMENT : usctpl01
45 *
46 * TEST CASE TOTAL : 2
47 *
48 * WALL CLOCK TIME : 1
49 *
50 * CPU TYPES : ALL
51 *
52 * AUTHOR : Richard Logan
53 *
54 * CO-PILOT : William Roske
55 *
56 * DATE STARTED : 03/31/94
57 *
58 * INITIAL RELEASE : UNICOS 7.0
59 *
60 * TEST CASES
61 *
62 * 1.) link(2) returns...(See Description)
63 *
64 * INPUT SPECIFICATIONS
65 * The standard options for system call tests are accepted.
66 * (See the parse_opts(3) man page).
nstraz090ed002000-08-04 20:48:22 +000067 * -N #links : Use #links links every iteration
68 *
69 * OUTPUT SPECIFICATIONS
70 *
71 * DURATION
72 * Terminates - with frequency and infinite modes.
73 *
74 * SIGNALS
75 * Uses SIGUSR1 to pause before test if option set.
76 * (See the parse_opts(3) man page).
77 *
78 * RESOURCES
79 * None
80 *
81 * ENVIRONMENTAL NEEDS
82 * No run-time environmental needs.
83 *
84 * SPECIAL PROCEDURAL REQUIREMENTS
85 * None
86 *
87 * INTERCASE DEPENDENCIES
88 * None
89 *
90 * DETAILED DESCRIPTION
91 * This is a Phase I test for the link(2) system call. It is intended
92 * to provide a limited exposure of the system call, for now. It
93 * should/will be extended when full functional tests are written for
94 * link(2).
95 *
96 * Setup:
97 * Setup signal handling.
98 * Pause for SIGUSR1 if option specified.
99 *
100 * Test:
101 * Loop if the proper options are given.
102 * Execute system call
103 * Check return code, if system call failed (return=-1)
104 * Log the errno and Issue a FAIL message.
105 * Otherwise, Issue a PASS message.
106 *
107 * Cleanup:
108 * Print errno log and/or timing stats if options given
109 *
110 *
111 *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
112
113#include <sys/types.h>
114#include <sys/fcntl.h>
115#include <sys/stat.h>
116#include <errno.h>
nstraz94181082000-08-30 18:43:38 +0000117#include <string.h>
nstraz090ed002000-08-04 20:48:22 +0000118#include <signal.h>
119#include "test.h"
120#include "usctest.h"
121
nstraz94181082000-08-30 18:43:38 +0000122void setup();
123void help();
nstraz090ed002000-08-04 20:48:22 +0000124void cleanup();
125
126
127
128char *TCID="link03"; /* Test program identifier. */
129int TST_TOTAL=2; /* Total number of test cases. */
130extern int Tst_count; /* Test Case counter for tst_* routines */
131extern int Tst_nobuf;
132
133int exp_enos[]={0, 0};
134
135#define BASENAME "lkfile"
136
137char Basename[255];
138char Fname[255];
139int Nlinks=0;
140char *Nlinkarg;
141
nstraz090ed002000-08-04 20:48:22 +0000142int Nflag=0;
143
144
145/* for test specific parse_opts options */
146option_t options[] = {
nstraz090ed002000-08-04 20:48:22 +0000147 { "N:", &Nflag, &Nlinkarg }, /* -N #links */
148 { NULL, NULL, NULL }
149};
150
151/***********************************************************************
152 * Main
153 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000154int
nstraz090ed002000-08-04 20:48:22 +0000155main(int ac, char **av)
156{
157 int lc; /* loop counter */
158 char *msg; /* message returned from parse_opts */
159 struct stat fbuf, lbuf;
160 int cnt;
161 int nlinks;
162 char lname[255];
163
164 Tst_nobuf=1;
165
166 /***************************************************************
167 * parse standard options
168 ***************************************************************/
nstraz94181082000-08-30 18:43:38 +0000169 if ( (msg=parse_opts(ac, av, options, &help)) != (char *) NULL ) {
nstraz090ed002000-08-04 20:48:22 +0000170 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
171 tst_exit();
172 }
173
nstraz090ed002000-08-04 20:48:22 +0000174 if ( Nflag ) {
175 if (sscanf(Nlinkarg, "%i", &Nlinks) != 1 ) {
176 tst_brkm(TBROK, NULL, "--N option arg is not a number");
177 tst_exit();
178 }
179 if ( Nlinks > 1000 ) {
180 tst_resm(TWARN, "--N option arg > 1000 - may get errno:%d (EMLINK)",
181 EMLINK);
182 }
183 }
184
185 /***************************************************************
186 * perform global setup for test
187 ***************************************************************/
188 setup();
189
190 /* set the expected errnos... */
191 TEST_EXP_ENOS(exp_enos);
192
193 /***************************************************************
194 * check looping state if -c option given
195 ***************************************************************/
196 for (lc=0; TEST_LOOPING(lc); lc++) {
197
198 /* reset Tst_count in case we are looping. */
199 Tst_count=0;
200
201 if ( Nlinks )
202 nlinks = Nlinks;
203 else
204 /* min of 10 links and max of a 100 links */
205 nlinks = (lc%90)+10;
206
207 for(cnt=1; cnt < nlinks; cnt++) {
208
209 sprintf(lname, "%s%d", Basename, cnt);
210 /*
211 * Call link(2)
212 */
213 TEST(link(Fname, lname));
214
215 /* check return code */
216 if ( TEST_RETURN == -1 ) {
217 TEST_ERROR_LOG(TEST_ERRNO);
218 tst_brkm(TFAIL, cleanup, "link(%s, %s) Failed, errno=%d : %s",
219 Fname, lname, TEST_ERRNO, strerror(TEST_ERRNO));
220 }
221 }
222
223 /***************************************************************
224 * only perform functional verification if flag set (-f not given)
225 ***************************************************************/
226 if ( STD_FUNCTIONAL_TEST ) {
227 stat(Fname, &fbuf);
228
229 for(cnt=1; cnt < nlinks; cnt++) {
230 sprintf(lname, "%s%d", Basename, cnt);
231
232 stat(lname, &lbuf);
233 if ( fbuf.st_nlink <= 1 || lbuf.st_nlink <= 1 ||
234 (fbuf.st_nlink != lbuf.st_nlink) ) {
235
236 tst_resm(TFAIL,
237 "link(%s, %s[1-%d]) ret %d for %d files, stat values do not match %d %d",
238 Fname, Basename, nlinks, TEST_RETURN, nlinks,
239 fbuf.st_nlink, lbuf.st_nlink);
240 break;
241 }
242 }
243 if ( cnt >= nlinks ) {
244 tst_resm(TPASS,
245 "link(%s, %s[1-%d]) ret %d for %d files, stat linkcounts match %d",
246 Fname, Basename, nlinks, TEST_RETURN, nlinks,
247 fbuf.st_nlink);
248 }
249 }
250 else
251 Tst_count++;
252
253 for(cnt=1; cnt < nlinks; cnt++) {
254
255 sprintf(lname, "%s%d", Basename, cnt);
256
257 if (unlink(lname) == -1) {
258 tst_res(TWARN, "unlink(%s) Failed, errno=%d : %s",
259 Fname, errno, strerror(errno));
260 }
261 }
262
263 } /* End for TEST_LOOPING */
264
265 /***************************************************************
266 * cleanup and exit
267 ***************************************************************/
268 cleanup();
nstraz94181082000-08-30 18:43:38 +0000269
270 return 0;
nstraz090ed002000-08-04 20:48:22 +0000271} /* End main */
272
273/***************************************************************
274 * help
275 ***************************************************************/
276void
277help()
278{
nstraz090ed002000-08-04 20:48:22 +0000279 printf(" -N #links : create #links hard links every iteration\n");
280}
281
282/***************************************************************
283 * setup() - performs all ONE TIME setup for this test.
284 ***************************************************************/
285void
286setup()
287{
288 int fd;
289
290 /* capture signals */
291 tst_sig(NOFORK, DEF_HANDLER, cleanup);
292
293 /* make a temp directory and cd to it */
294 tst_tmpdir();
295
296 /* Pause if that option was specified */
297 TEST_PAUSE;
298
299 sprintf(Fname,"%s_%d", BASENAME, getpid());
300 if ((fd = open(Fname,O_RDWR|O_CREAT,0700)) == -1) {
301 tst_brkm(TBROK, cleanup,
302 "open(%s, O_RDWR|O_CREAT,0700) Failed, errno=%d : %s",
303 Fname, errno, strerror(errno));
304 } else if (close(fd) == -1) {
305 tst_res(TWARN, "close(%s) Failed, errno=%d : %s",
306 Fname, errno, strerror(errno));
307 }
308 sprintf(Basename, "%s_%d.", BASENAME, getpid());
309} /* End setup() */
310
311
312/***************************************************************
313 * cleanup() - performs all ONE TIME cleanup for this test at
314 * completion or premature exit.
315 ***************************************************************/
316void
317cleanup()
318{
319 /*
320 * print timing stats if that option was specified.
321 * print errno log if that option was specified.
322 */
323 TEST_CLEANUP;
324
325 /* Remove tmp dir and all files in it */
326 tst_rmdir();
327
328 /* exit with return code appropriate for results */
329 tst_exit();
330} /* End cleanup() */