blob: ba7fe280d8c77d6ce737e74dd048288bcdbd0a8f [file] [log] [blame]
alaffin00657852000-07-27 17:26:25 +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 */
nstraz94181082000-08-30 18:43:38 +000032/* $Id: symlink01.c,v 1.3 2000/08/30 18:43:38 nstraz Exp $ */
alaffin00657852000-07-27 17:26:25 +000033/**********************************************************
34*
alaffin81a90652000-07-31 22:41:24 +000035* OS Test - Silicon Graphics, Inc.
alaffin00657852000-07-27 17:26:25 +000036*
alaffin81a90652000-07-31 22:41:24 +000037* TEST IDENTIFIER : symlink01 (symlink)
alaffin00657852000-07-27 17:26:25 +000038*
39* TEST TITLE : Make a Symbolic Link to a File
40*
41* PARENT DOCUMENT : symtds01
42*
43* TEST CASE TOTAL : 5
44*
45* WALL CLOCK TIME : 3
46*
alaffin81a90652000-07-31 22:41:24 +000047* TEST IDENTIFIER : readlink01 (readlink)
alaffin00657852000-07-27 17:26:25 +000048*
49* TEST TITLE : Reads Value of a Symbolic Link
50*
51* PARENT DOCUMENT : symtds01
52*
53* TEST CASE TOTAL : 4
54*
55* WALL CLOCK TIME : 3
56*
alaffin81a90652000-07-31 22:41:24 +000057* TEST IDENTIFIER : stat04 (stat)
alaffin00657852000-07-27 17:26:25 +000058*
59* TEST TITLE : Gets File Status Indirectly From a Symbolic Link
60* File
61*
62* PARENT DOCUMENT : symtds01
63*
64* TEST CASE TOTAL : 3
65*
66* WALL CLOCK TIME : 3
67*
alaffin81a90652000-07-31 22:41:24 +000068* TEST IDENTIFIER : lstat01 (lstat)
alaffin00657852000-07-27 17:26:25 +000069*
70* TEST TITLE : Get file Status About a Symbolic Link File
71*
72* PARENT DOCUMENT : symtds01
73*
74* TEST CASE TOTAL : 3
75*
76* WALL CLOCK TIME : 3
77*
alaffin81a90652000-07-31 22:41:24 +000078* TEST IDENTIFIER : mkdir05 (mkdir)
alaffin00657852000-07-27 17:26:25 +000079*
80* TEST TITLE : Fail When Making a Directory File Indirectly From
81* a Symbolic Link File
82*
83* PARENT DOCUMENT : symtds01
84*
85* TEST CASE TOTAL : 1
86*
87* WALL CLOCK TIME : 3
88*
alaffin81a90652000-07-31 22:41:24 +000089* TEST IDENTIFIER : rmdir03 (rmdir)
alaffin00657852000-07-27 17:26:25 +000090*
91* TEST TITLE : Fail When Removing a Directory File Indirectly
92* From a Symbolic Link File
93*
94* PARENT DOCUMENT : symtds01
95*
96* TEST CASE TOTAL : 1
97*
98* WALL CLOCK TIME : 3
99*
alaffin81a90652000-07-31 22:41:24 +0000100* TEST IDENTIFIER : chdir01 (chdir)
alaffin00657852000-07-27 17:26:25 +0000101*
102* TEST TITLE : Changes Current Working DIrectory Location
103* Indirectly From a Symbolic Link File
104*
105* PARENT DOCUMENT : symtds01
106*
107* TEST CASE TOTAL : 3
108*
109* WALL CLOCK TIME : 3
110*
alaffin81a90652000-07-31 22:41:24 +0000111* TEST IDENTIFIER : link01 (link)
alaffin00657852000-07-27 17:26:25 +0000112*
113* TEST TITLE : Creates a Link To a File Indirectly From a
114* Symbolic Link File
115*
116* PARENT DOCUMENT : symtds01
117*
118* TEST CASE TOTAL : 3
119*
120* WALL CLOCK TIME : 3
121*
alaffin81a90652000-07-31 22:41:24 +0000122* TEST IDENTIFIER : unlink01 (unlink)
alaffin00657852000-07-27 17:26:25 +0000123*
124* TEST TITLE : Removes a Link To a File And Not Any Object File
125* Which Maybe Pointed At
126*
127* PARENT DOCUMENT : symtds01
128*
129* TEST CASE TOTAL : 1
130*
131* WALL CLOCK TIME : 3
132*
alaffin81a90652000-07-31 22:41:24 +0000133* TEST IDENTIFIER : chmod01 (chmod)
alaffin00657852000-07-27 17:26:25 +0000134*
135* TEST TITLE : Change Object File Permissions Indirectly From a
136* Symbolic Link File
137*
138* PARENT DOCUMENT : symtds01
139*
140* TEST CASE TOTAL : 3
141*
142* WALL CLOCK TIME : 3
143*
alaffin81a90652000-07-31 22:41:24 +0000144* TEST IDENTIFIER : utime01 (utime)
alaffin00657852000-07-27 17:26:25 +0000145*
146* TEST TITLE : Set File Access And Modify Object File Times
147* Indirectly From a Symbolic Link File
148*
149* PARENT DOCUMENT : symtds01
150*
151* TEST CASE TOTAL : 3
152*
153* WALL CLOCK TIME : 3
154*
alaffin81a90652000-07-31 22:41:24 +0000155* TEST IDENTIFIER : rename01 (rename)
alaffin00657852000-07-27 17:26:25 +0000156*
157* TEST TITLE : Rename a Symbolic Link File And Not Any Object
158* File
159*
160* PARENT DOCUMENT : symtds01
161*
162* TEST CASE TOTAL : 3
163*
164* WALL CLOCK TIME : 3
165*
alaffin81a90652000-07-31 22:41:24 +0000166* TEST IDENTIFIER : open01 (open)
alaffin00657852000-07-27 17:26:25 +0000167*
168* TEST TITLE : Create/Open a File For Reading Or Writing
169* Indirectly From a Symbolic Link File
170*
171* PARENT DOCUMENT : symtds01
172*
173* TEST CASE TOTAL : 5
174*
175* WALL CLOCK TIME : 3
176*
177* EXECUTED BY : whom ever
178*
179* CPU TYPES : ALL
180*
181* AUTHOR : David Fenner
182*
183* CO-PILOT : Jon Hendrickson
184*
185* DATE STARTED : 07/25/90
186*
187* INITIAL RELEASE : UNICOS 6.0
188*
189* TEST CASES
190*
191* For symlink
192*
193* 1. Create symbolic link with abnormal object name path
194* 2. Create symbolic link with normal object name path
195* 3. Create symbolic link with path to an existing object file
196* 4. Receive EEXIST error when creating an already existing symbolic link file.
197* 5. Receive ENAMETOOLONG error when creating symbolic link which exceeds PATH_MAX in length
198*
199* For readlink
200*
201* 1. Read a symbolic link file which points at no object file
202* 2. Read a symbolic link file which points at an object file
203* 3. Receive ENAMETOOLONG error when reading symbolic link which exceeds PATH_MAX in length
204* 4. Receive an EINVAL error when reading a file which is not a symbolic
205* link file.
206*
207* For stat
208*
209* 1. Get object file status through symbolic link file
210* 2. Receive ENOENT error when accessing non-existent object file through symbolic link file
211* 3. Receive ELOOP error when nesting of symbolic links exceed maximum
212*
213* For lstat
214*
215* 1. Get symbolic link file status when pointing at no object file
216* 2. Get symbolic link file status when pointing at an object file
217* 3. Get object file status when argument is not a symbolic link
218* file.
219*
220* For mkdir
221*
222* 1. Receive EEXIST error when creating a directory through a symbolic link file
223*
224* For rmdir
225*
226* 1. Receive ENOTDIR error when removing an existing directory through a symbolic link file
227*
228* For chdir
229*
230* 1. Change current working directory through a symbolic link file
231* 2. Receive ENOENT error when accessing non-existent directory through symbolic link file
232* 3. Receive ELOOP error when nesting of symbolic links exceed maximum
233*
234* For link
235*
236* 1. Link an object file to a new file through symbolic link file
237* 2. Receive ENOENT error when accessing non-existent object file through symbolic link file
238* 3. Receive ELOOP error when nesting of symbolic links exceed maximum
239*
240* For unlink
241*
242* 1. Delete a symbolic link file and not the object file which it points at
243*
244* For chmod
245*
246* 1. Change file permissions of object file through a symbolic link file
247* 2. Receive ENOENT error when accessing non-existent directory through symbolic link file
248* 3. Receive ELOOP error when nesting of symbolic links exceed maximum
249*
250* For utime
251*
252* 1. Change inode times of object file through a symbolic link file
253* 2. Receive ENOENT error when accessing non-existent directory through symbolic link file
254* 3. Receive ELOOP error when nesting of symbolic links exceed maximum
255*
256* For rename
257*
258* 1. Rename a symbolic link file which points at no object file
259* 2. Rename a symbolic link file which points at an object file without any object file alterations.
260* 3. Receive EXDEV when trying to rename a symbolic link file to an address outside of current file system
261*
262* For open
263*
264* 1. Create an object file through a symbolic link file
265* 2. Open an object file through a symbolic link file
266* 3. Receive EEXIST error when exclusively creating an object file through a symbolic link file
267* 4. Receive ENOENT error when accessing non-existent object file through symbolic link file
268* 5. Receive ELOOP error when nesting of symbolic links exceed maximum
269*
270* ENVIRONMENTAL NEEDS
271* None
272*
273* DETAILED DESCRIPTION
274*
275* Self-documenting code so see below
276*
277*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
278
279#include <stdio.h>
280#include <signal.h>
281#include <string.h>
282#include <fcntl.h> /* open(2) system call */
283#include <errno.h>
284#include <sys/types.h>
285#include <utime.h> /* utime(2) system call */
286#include <sys/param.h>
287#include <sys/stat.h> /* stat(2) and lstat(2) system calls */
288
289#include "test.h"
290#include "usctest.h"
291
292void setup();
293void cleanup();
294void help();
295void delete_files();
296void do_EEXIST();
297void do_ENOENT();
298void do_ELOOP();
299void do_ENOTDIR();
300void do_EXDEV();
301void do_ENAMETOOLONG();
302void do_EINVAL();
303void do_readlink();
304void do_stat();
305void do_chdir();
306void do_link();
307void do_unlink();
308void do_chmod();
309void do_utime();
310void do_rename();
311void do_open();
312
313#define S_FILE "symbolic" /* Name of symbolic link file */
314#define O_FILE "object" /* Name of object file */
315#define A_S_FILE "asymbolic" /* Another name for a symbolic link file */
316#define Y_A_S_FILE "/NiCkEr" /* Yet another symbolic link file */
317#define BIG_STRING "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
318
alaffin81a90652000-07-31 22:41:24 +0000319#define DEFAULT_TCID "symlink01"
alaffin00657852000-07-27 17:26:25 +0000320
alaffin81a90652000-07-31 22:41:24 +0000321#define SYMLINK "symlink01"
322#define READLINK "readlink01"
323#define STAT "stat04"
324#define LSTAT "lstat01"
325#define MKDIR "mkdir05"
326#define RMDIR "rmdir03"
327#define CHDIR "chdir01"
328#define LINK "link01"
329#define UNLINK "unlink01"
330#define CHMOD "chmod01"
331#define UTIME "utime01"
332#define RENAME "rename01"
333#define OPEN "open01"
alaffin00657852000-07-27 17:26:25 +0000334
335#define cktcsid(s1,s2) (!strcmp(s1,s2))
336#define BUFMAX 512
337#define MODE 0700
338#define MASK 0100777 /* A regular file with r,w,x for all mask */
339
340/*
341 * Lets be optimistic and only define messages for passing test cases
342 */
343char *msgs[] = {
344 "Creation of symbolic link file to no object file is ok",
345 "Creation of symbolic link file and object file via symbolic link is ok",
346 "Creating an existing symbolic link file error is caught",
347 "Creating a symbolic link which exceeds maximum pathname error is caught",
348 "Reading of symbolic link file contents checks out ok",
349 "Reading a symbolic link which exceeds maximum pathname error is caught",
350 "Getting stat info about object file through symbolic link file is ok",
351 "Stat(2) error when accessing non-existent object through symbolic link is caught",
352 "lstat(2) of symbolic link file which points to no object file is ok",
353 "lstat(2) of symbolic link file which points at an object file is ok",
354 "mkdir(2) of object file through symbolic link file failed as expected",
355 "rmdir(2) of object file through symbolic link file failed as expected",
356 "chdir(2) to object file location through symbolic link file is ok",
357 "chdir(2) to non-existent object file location through symbolic link file failed as expected",
358 "link(2) to a symbolic link, which is pointing to an existing object file worked - file created and link count adjusted",
359 "link(2) to a symbolic link, which is pointing to a non-existing object file worked ok - file created and link count adjusted.",
360 "unlink(2) of symbolic link file with no object file removal is ok",
361 "chmod(2) of object file permissions through symbolic link file is ok",
362 "chmod(2) error when accessing non-existent object through symbolic link is caught",
363 "utime(2) change of object file access and modify times through symbolic link file is ok",
364 "utime(2) error when accessing non-existent object through symbolic link is caught",
365 "rename(3) of symbolic link file name which points at no object file is ok",
366 "rename(3) of symbolic link file name which points at object file is ok",
367 "rename(3) error of symbolic link file name across file systems is caught",
368 "open(2) with (O_CREAT | O_RDWR) to create object file through symbolic link file and all writes, reads, and lseeks are ok",
369 "open(2) with O_RDWR of existing object file through symbolic link file and all writes, reads, and lseeks are ok",
370 "open(2) with (O_CREAT | O_EXCL) error is caught when creating object file through symbolic link file",
371 "open(2) error with O_RDWR is caught when processing symbolic link file which points at no object file",
372 "Nested symbolic link access condition caught. ELOOP is returned",
373 "Reading a nonsymbolic link file error condition is caught. EINVAL is returned",
374 "lstat(2) of object file returns object file inode information",
375 "NULL"
376};
377
378/*
379 * Define test object setup and validation functions
380 */
381int creat_both(), creat_symlink(), creat_path_max(), ck_symlink(),
382 creat_object(), ck_object(), ck_both(), ck_path_max();
383
384
385/*
386 * Define test cases
387 */
388struct all_test_cases
389{
390 char *tcid;
391 int test_fail;
392 int errno_val;
393 int pass_msg;
394 int (*test_setup)();
395 int (*ck_test)();
396 char *fn_arg[3];
397
398} test_objects[] = {
nstraz94181082000-08-30 18:43:38 +0000399 {SYMLINK, 0, 0, 0, creat_symlink, ck_symlink, {"%bc+eFhi!k", S_FILE, NULL}},
400 {SYMLINK, 0, 0, 0, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
401 {SYMLINK, 0, 0, 1, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
402 {SYMLINK, 1, EEXIST, 2, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
403 {SYMLINK, 1, ENAMETOOLONG, 3, creat_path_max, ck_path_max, {O_FILE, S_FILE, NULL}},
404 {READLINK, 0, 0, 4, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
405 {READLINK, 0, 0, 4, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
406 {READLINK, 1, ENAMETOOLONG, 5, creat_path_max, ck_path_max, {O_FILE, S_FILE, NULL}},
407 {READLINK, 1, EINVAL, 29, creat_object, ck_object, {O_FILE, NULL, NULL}},
408 {STAT, 0, 0, 6, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
409 {STAT, 1, ENOENT, 7, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
410 {STAT, 1, ELOOP, 28, creat_symlink, ck_symlink, {S_FILE, S_FILE, NULL}},
411 {LSTAT, 0, 0, 8, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
412 {LSTAT, 0, 0, 9, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
413 {LSTAT, 0, 0, 30, creat_object, ck_object, {O_FILE, NULL, NULL}},
414 {MKDIR, 1, EEXIST, 10, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
415 {RMDIR, 1, ENOTDIR, 11, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
416 {CHDIR, 0, 0, 12, creat_symlink, ck_symlink, {O_FILE, S_FILE, O_FILE}},
417 {CHDIR, 1, ENOENT, 13, creat_symlink, ck_symlink, {"%bc+eFhi!k", S_FILE, NULL}},
418 {CHDIR, 1, ELOOP, 28, creat_symlink, ck_symlink, {S_FILE, S_FILE, NULL}},
419 {LINK, 0, 0, 14, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
420 {LINK, 0, 0, 15, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
421 /* The following link test case is invalid - leaving it defined so */
422 /* I don't have to change all the entries in the all_tcses array after link */
423 {LINK, 1, -1, -1, creat_symlink, ck_symlink, {NULL, NULL, NULL}},
424 {UNLINK, 0, 0, 16, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
425 {CHMOD, 0, 0, 17, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
426 {CHMOD, 1, ENOENT, 18, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
427 {CHMOD, 1, ELOOP, 28, creat_symlink, ck_symlink, {S_FILE, S_FILE, NULL}},
428 {UTIME, 0, 0, 19, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
429 {UTIME, 1, ENOENT, 20, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
430 {UTIME, 1, ELOOP, 28, creat_symlink, ck_symlink, {S_FILE, S_FILE, NULL}},
431 {RENAME, 0, 0, 21, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
432 {RENAME, 0, 0, 22, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
433 {RENAME, 1, EXDEV, 23, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
434 {OPEN, 0, 0, 24, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
435 {OPEN, 0, 0, 25, creat_both, ck_both, {O_FILE, S_FILE, O_FILE}},
436 {OPEN, 1, EEXIST, 26, creat_symlink, ck_symlink, {O_FILE, S_FILE, O_FILE}},
437 {OPEN, 1, ENOENT, 27, creat_symlink, ck_symlink, {O_FILE, S_FILE, NULL}},
438 {OPEN, 1, ELOOP, 28, creat_symlink, ck_symlink, {S_FILE, S_FILE, NULL}}
alaffin00657852000-07-27 17:26:25 +0000439};
440
441/*
442 * Define tcses
443 */
444struct tcses
445{
446 char *tcid;
447 char *syscall;
448 int test_cases; /* number of entries in test_objects array */
449 struct all_test_cases *tc_ptr;
450 char *desc;
451} all_tcses[] = {
452
453 { SYMLINK, "symlink", 5, &test_objects[0],
454 "Make a Symbolic Link to a File" },
455 { READLINK, "readlink", 4, &test_objects[5],
456 "Reads Value of a Symbolic Link" },
457 { STAT, "stat", 3, &test_objects[9],
458 "Gets File Status Indirectly From a Symbolic Link file" },
459 { LSTAT, "lstat", 3, &test_objects[12],
460 "Get file Status About a Symbolic Link File" },
461 { MKDIR, "mkdir", 1, &test_objects[15],
462 "Fail When Making a Directory File Indirectly from a symlink" },
463 { RMDIR, "rmdir", 1, &test_objects[16],
464 "Fail When Removing a Directory File Indirectly from a symlink" },
465 { CHDIR, "chdir", 3, &test_objects[17],
466 "Changes CWD Location Indirectly from a symlink" },
467 { LINK, "link", 2, &test_objects[20],
468 "Creates a Link To a File Indirectly From a Symbolic" },
469 { UNLINK, "unlink", 1, &test_objects[23],
470 "Removes a Link To a File but not the Object File" },
471 { CHMOD, "chmod", 3, &test_objects[24],
472 "Change Object File Permissions Indirectly From a Symbolic" },
473 { UTIME, "utime", 3, &test_objects[27],
474 "Set File Access And Modify Object File Times via symlink" },
475 { RENAME, "rename", 3, &test_objects[30],
476 "Rename a Symbolic Link File And Not Any Object file" },
477 { OPEN, "open", 5, &test_objects[33],
478 "Create/Open a File For Reading Or Writing via symlink" },
479};
480
481/*
482 * Define GLOBAL variables
483 */
484
485int TST_TOTAL;
486int TEST_RESULT;
487time_t a_time_value = 100;
488char *TCID;
489char *Selectedtests = NULL; /* Name (tcid) of selected test cases */
490char test_msg[BUFMAX];
491char full_path[PATH_MAX+1];
492extern int Tst_count;
493extern char *TESTDIR;
494extern char *strrchr();
495extern int errno;
496
497struct stat asymlink, statter;
498char Buffer[1024];
499char Buf[1024];
500
alaffin00657852000-07-27 17:26:25 +0000501char *Tcid = NULL;
502
503option_t Options[] = {
alaffin00657852000-07-27 17:26:25 +0000504 { "T:", NULL, &Tcid }, /* -T tcid option */
505 { NULL, NULL, NULL }
506};
507
508/***********************************************************************
509 * MAIN
510 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000511int
512main(int argc, char *argv[])
alaffin00657852000-07-27 17:26:25 +0000513{
alaffin00657852000-07-27 17:26:25 +0000514 struct tcses *tcs_ptr, *get_tcs_info();
515 int do_syscalltests();
516 void cleanup();
517 int lc; /* loop counter */
518 char *msg; /* message returned from parse_opts */
519
520
521 /***************************************************************
522 * parse standard options, and exit if there is an error
523 ***************************************************************/
nstraz94181082000-08-30 18:43:38 +0000524 if ( (msg=parse_opts(argc, argv, Options, &help)) != (char *) NULL ) {
alaffin00657852000-07-27 17:26:25 +0000525 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
526 tst_exit();
527 }
528
529 /*
530 * If the -T option was used, use that TCID or use the default
531 */
532 if ( Tcid != NULL ) {
533 TCID = Tcid;
534 Selectedtests=Tcid;
535
536 }
537#ifndef ALL
538 else {
539 TCID = DEFAULT_TCID;
540 Selectedtests = DEFAULT_TCID;
541 }
542#endif
543
alaffin00657852000-07-27 17:26:25 +0000544 /*
545 * Get test case specification information and assign TST_TOTAL
546 */
547 if ((tcs_ptr=get_tcs_info(Selectedtests)) == NULL) {
548 TST_TOTAL=1;
549 tst_brkm(TBROK, cleanup,
550 "Unknown symbolic link test case specification executed");
551 }
552
553 /***************************************************************
554 * perform global setup for test
555 ***************************************************************/
556
557 setup();
558
559 /***************************************************************
560 * check looping state if -c option given
561 ***************************************************************/
562 for (lc=0; TEST_LOOPING(lc); lc++) {
563
564 /* reset Tst_count in case we are looping. */
565 Tst_count=0;
566
567 /*
568 * Execute tcs testing function and all defined test cases
569 */
570 do_syscalltests(tcs_ptr);
571
572 } /* End for TEST_LOOPING */
573
nstraz94181082000-08-30 18:43:38 +0000574 /*
575 * End appropriately
576 */
577 cleanup();
578
579 return 0;
alaffin00657852000-07-27 17:26:25 +0000580}
581
582/***********************************************************************
583 * This function maps the name of the process to a test case specification
584 * defined in the all_tcses array of tcses structures. Either a pointer
585 * to the mapped test case specification information is returned or a
586 * null pointer.
587 *
588 * Argument is path to program name.
589 ***********************************************************************/
590struct tcses *get_tcs_info(ptr)
591char *ptr;
592{
593 int ctr;
nstraz94181082000-08-30 18:43:38 +0000594 struct tcses *tcs_ptr;
alaffin00657852000-07-27 17:26:25 +0000595
596#if ALL
597 if ( ptr == NULL ) {
598
599 TST_TOTAL=0;
600 for (ctr=1; ctr < sizeof(all_tcses)/sizeof(struct tcses); ctr++)
601 TST_TOTAL += all_tcses[ctr].test_cases;
602 return all_tcses;
603 }
604#endif
605
606
607 for(ctr=0; ctr < (sizeof(all_tcses)/sizeof(struct tcses)); ctr++) {
608 if ( strcmp(ptr, all_tcses[ctr].tcid) == 0 ||
609 strcmp(ptr, all_tcses[ctr].syscall) == 0 ) {
610 tcs_ptr = &all_tcses[ctr];
611 TCID = all_tcses[ctr].tcid;
612 TST_TOTAL=tcs_ptr->test_cases;
613 return(tcs_ptr);
614 }
615
616 }
617 return(NULL);
618}
619
620/***********************************************************************
621 * Determines if what path points at is a symbolic link file
622 *
623 * Argument is path to symbolic link file.
624 *
625 * Return status is one if a symbolic link file. Zero if not a symbolic
626 * link file and a minus one if the path doesn't point at a file.
627 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000628int
alaffin00657852000-07-27 17:26:25 +0000629see_if_a_symlink(path)
630char *path;
631{
632 if (lstat(path, &asymlink) < 0)
633 return(-1);
634
635 if ((asymlink.st_mode & S_IFMT) == S_IFLNK)
636 return(1);
637 else
638 return(0);
639}
640
641/***********************************************************************
642 * This function performs without any hesitation, file(s) deletions
643 ***********************************************************************/
644void
645delete_files(path1, path2)
646char *path1, *path2;
647{
648 unlink(path1);
649 unlink(path2);
650}
651
652/***********************************************************************
653 *
654 * This routine creates a symbolic link file.
655 *
656 * Argument one is symbolic link pathname to point at.
657 * Argument two is name of symbolic link file.
658 *
659 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000660int
alaffin00657852000-07-27 17:26:25 +0000661creat_symlink(path1, path2)
662char *path1, *path2;
663{
664 TEST( symlink(path1, path2) );
665 errno=TEST_ERRNO;
666 if (TEST_RETURN == -1) {
667 TEST_RESULT=TBROK;
668 sprintf(test_msg,
669 "symlink(2) Failure when creating setup %s object file: errno:%d %s",
670 path1, errno, strerror(errno));
671 return(0);
672 }
673 else {
674 sprintf(Buf, "symlink(%s, %s) was succesful.\n", path1, path2);
675 strcat(Buffer, Buf);
676#if DEBUG
677 tst_resm(TPASS, "symlink(%s, %s) was succesful.", path1, path2);
678#endif
679 }
680 return(1);
681}
682
683/***********************************************************************
684 *
685 * This routine creates a regular file.
686 *
687 * Argument one is a pathname
688 *
689 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000690int
alaffin00657852000-07-27 17:26:25 +0000691creat_object(path1)
692char *path1;
693{
694 int fd;
695 if ((fd=creat(path1, MODE)) == -1) {
696 TEST_RESULT=TBROK;
697 sprintf(test_msg,
698 "creat(2) Failure when creating setup %s object file: errno:%d %s",
699 path1, errno, strerror(errno));
700 return(0);
701 }
702 else {
703 sprintf(Buf, "creat(%s, %#o) was succesful.\n", path1, MODE);
704 strcat(Buffer, Buf);
705#if DEBUG
706 tst_resm(TPASS, "creat(%s, %#o) was succesful.", path1, MODE);
707#endif
708 }
709 if (close(fd) == -1) {
710 TEST_RESULT=TBROK;
711 sprintf(test_msg,
712 "close(2) Failure when closing setup %s object file: errno:%d %s",
713 path1, errno, strerror(errno));
714 return(0);
715 }
716 return(1);
717}
718
719/***********************************************************************
720 *
721 * This routine creates a symbolic link file and a regular file.
722 *
723 * Argument one is a pathname of object file
724 * Argument two is symbolic link file name
725 * Argument three is regular file name
726 *
727 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000728int
alaffin00657852000-07-27 17:26:25 +0000729creat_both(path1, path2, path3)
730char *path1, *path2, *path3;
731{
732 if (creat_symlink(path1, path2) == -1)
733 return(0);
734 else if (creat_object(path3) == -1)
735 return(0);
736 return(1);
737}
738
739/***********************************************************************
740 *
741 * This routine checks if symbolic link file is a symbolic link file.
742 *
743 * Argument one is a pathname of object file
744 * Argument two is symbolic link file name
745 * Argument three is regular file name
746 *
747 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000748int
alaffin00657852000-07-27 17:26:25 +0000749ck_symlink(path1, path2, path3)
750char *path1, *path2, *path3;
751{
752 int ret;
753
754 if ((ret=see_if_a_symlink(path2)) == -1) {
755 TEST_RESULT=TBROK;
756 sprintf(test_msg,
757 "lstat(2) Failure when accessing %s symbolic link file which should contain %s path to %s file ",
758 path2, path1, path3);
759 return(0);
760 }
761 else if (ret == 0) {
762 TEST_RESULT=TBROK;
763 sprintf(test_msg,
764 "%s is not a symbolic link file which contains %s path to %s file",
765 path2, path1, path3);
766 return(0);
767 }
768 return(1);
769}
770
771/***********************************************************************
772 *
773 * This routine checks if symbolic link file points at object file.
774 *
775 * Argument one is a pathname of object file
776 * Argument two is symbolic link file name
777 * Argument three is regular file name
778 *
779 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000780int
alaffin00657852000-07-27 17:26:25 +0000781ck_both(path1, path2, path3)
782char *path1, *path2, *path3;
783{
784 if (ck_symlink(path1, path2, path3) == 0)
785 return(0);
786 else if ((stat(path3, &statter) == -1) && (errno == ENOENT)) {
787 TEST_RESULT=TBROK;
788 sprintf(test_msg, "stat(2) Failure when accessing %s object file ", path3);
789 return(0);
790 }
791 else if ((stat(path2, &asymlink) == -1) && (errno == ENOENT)) {
792 TEST_RESULT=TBROK;
793 sprintf(test_msg, "stat(2) Failure when accessing %s symbolic link file ",
794 path2);
795 return(0);
796 }
797 else if (statter.st_ino != asymlink.st_ino) {
798 TEST_RESULT=TBROK;
799 sprintf(test_msg,
800 "stat(2) Failure when accessing %s object file through %s symbolic link file ",
801 path3, path2);
802 return(0);
803 }
804 return(1);
805
806}
807
808/***********************************************************************
809 * This routine populates full_path with a pathname whose length exceeds
810 * the PATH_MAX define value in param.h
811 *
812 * Argument one is a pathname of object file
813 * Argument two is symbolic link file name
814 * Argument three is regular file name
815 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000816int
alaffin00657852000-07-27 17:26:25 +0000817creat_path_max(path1, path2, path3)
818char *path1, *path2, *path3;
819{
820 int ctr, to_go, size, whole_chunks;
821 char *cwd, *getcwd();
822
823 if ((cwd = getcwd((char *)NULL, 64)) == NULL)
824 {
825 TEST_RESULT=TBROK;
826 sprintf(test_msg,
827 "getcwd(3) Failure in setup of %s %s %s test case object elements",
828 path1, path2, path3);
829 return(0);
830 }
831 cwd = getcwd((char *)NULL, 64);
832 size = strlen(cwd);
833
834 to_go = PATH_MAX - size;
835 size = strlen(path1);
836 whole_chunks = to_go / size;
837 strcpy(full_path, cwd);
838 for (ctr=0; ctr < whole_chunks; ctr++) {
839 strcat(full_path, path1);
840 }
841 size= strlen(full_path);
842 to_go = PATH_MAX - size;
843 strcat(full_path, "/");
844 for (ctr=0; ctr < to_go; ctr++)
845 strcat(full_path, "Z");
846
847 return(1);
848}
849
850/***********************************************************************
851 * This routine checks that full_path's length exceeds the PATH_MAX
852 * define value in param.h
853 *
854 * Argument one is a pathname of object file
855 * Argument two is symbolic link file name
856 * Argument three is regular file name
857 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000858int
alaffin00657852000-07-27 17:26:25 +0000859ck_path_max(path1, path2, path3)
860char *path1, *path2, *path3;
861{
862 if (strlen(full_path) == (PATH_MAX+1))
863 return(1);
864 else
865 {
866 TEST_RESULT=TBROK;
867 sprintf(test_msg, "%s %d %s %s %s %s",
868 "full_path character array length was not", (PATH_MAX+1),
869 "characters long for test case object elements",
870 path1, path2, path3);
871 return(0);
872 }
873}
874
875/***********************************************************************
876 * This routine checks if the stat(2) and lstat(2) calls return the same
877 * information when the path is not a symbolic link file
878 *
879 * Argument one is a pathname of object file
880 * Argument two is symbolic link file name
881 * Argument three is regular file name
882 *
883 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000884int
alaffin00657852000-07-27 17:26:25 +0000885ck_object(path1, path2, path3)
886char *path1, *path2, *path3;
887{
888 int ret;
889
890 if ((ret=see_if_a_symlink(path1)) < 0) {
891 TEST_RESULT=TFAIL;
892 sprintf(test_msg,
893 "lstat(2) failed to return inode information for a regular object file");
894 return(0);
895 }
896 else if (ret == 1) {
897 TEST_RESULT=TFAIL;
898 sprintf(test_msg,
899 "lstat(2) detected a regular object file as a symbolic link file");
900 return(0);
901 }
902 else if (stat(path1, &statter) == -1) {
903 TEST_RESULT=TBROK;
904 sprintf(test_msg,
905 "stat(2) failed to return inode information for a regular object file");
906 return(0);
907 }
908 else if (bcmp((char *)&statter, (char *)&asymlink, sizeof(statter)) != 0) {
909 TEST_RESULT=TFAIL;
910 sprintf(test_msg,
911 "lstat(2) and stat(2) do not return same inode information for an object file");
912 return(0);
913
914 }
915 return(1);
916}
917
918/***********************************************************************
919 * Main test case processing function
920 *
921 * Argument is a ptr into the all_tcses array of structures of type tcses
922 ***********************************************************************/
nstraz94181082000-08-30 18:43:38 +0000923int
alaffin00657852000-07-27 17:26:25 +0000924do_syscalltests(tcs)
925struct tcses *tcs;
926{
927 int ctr, ret;
928 struct all_test_cases *tc_ptr;
929
930 /*
931 * loop through desired number of test cases
932 */
933 for (ctr=0, tc_ptr=tcs->tc_ptr; ctr < TST_TOTAL; ctr++, tc_ptr++) {
934
935 Buffer[0]='\0';
936
937 /*
938 * If running all test cases for all tcid, set the TCID if needed.
939 */
940 if ( Selectedtests == NULL ) {
941 if ( strcmp(tcs->tcid, tc_ptr->tcid) != 0 ) {
942 TCID = tc_ptr->tcid;
943 Tst_count=0;
944 }
945 }
946 /*
947 * Insure that we are executing the correct tcs test case
948 */
949 if (strcmp(tcs->tcid, tc_ptr->tcid) != 0) {
950 tst_resm(TBROK, "%s TCID attempted to execute %s %d %d test case",
951 tcs->tcid, tc_ptr->tcid, tc_ptr->test_fail, tc_ptr->errno_val);
952 continue;
953 }
954 TEST_RESULT=TPASS;
955 delete_files(S_FILE, O_FILE);
956 /*
957 * Perform test case setup
958 */
959 ret = (tc_ptr->test_setup)(tc_ptr->fn_arg[0], tc_ptr->fn_arg[1],
960 tc_ptr->fn_arg[2], tc_ptr->errno_val);
961
962 /* If an expected error, try it out */
963
964 if (tc_ptr->test_fail) {
965 /*
966 * Try to perform test verification function
967 */
968 if (! (tc_ptr->ck_test)(tc_ptr->fn_arg[0], tc_ptr->fn_arg[1],
969 tc_ptr->fn_arg[2], tc_ptr->errno_val))
970 tst_resm(TEST_RESULT, test_msg);
971 else if (tc_ptr->errno_val == EEXIST)
972 do_EEXIST(tc_ptr);
973 else if (tc_ptr->errno_val == ENOENT)
974 do_ENOENT(tc_ptr);
975 else if (tc_ptr->errno_val == ELOOP)
976 do_ELOOP(tc_ptr);
977 else if (tc_ptr->errno_val == ENOTDIR)
978 do_ENOTDIR(tc_ptr);
979 else if (tc_ptr->errno_val == EXDEV)
980 do_EXDEV(tc_ptr);
981 else if (tc_ptr->errno_val == ENAMETOOLONG)
982 do_ENAMETOOLONG(tc_ptr);
983 else if (tc_ptr->errno_val == EINVAL)
984 do_EINVAL(tc_ptr);
985 else
986 tst_resm(TBROK, "Test Case Declaration Error");
987 }
988 else if (ret == 1) { /* No setup function error */
989
990 if (tc_ptr->errno_val != 0)
991 tst_resm(TBROK, "Test Case Declaration Error");
992 else {
993 /*
994 * Perform test verification function
995 */
996 ret=(tc_ptr->ck_test)(tc_ptr->fn_arg[0], tc_ptr->fn_arg[1],
997 tc_ptr->fn_arg[2], tc_ptr->errno_val);
998
999 /* Perform requested symbolic link system call test */
1000
1001 if ((cktcsid(tc_ptr->tcid, SYMLINK)) ||
1002 (cktcsid(tc_ptr->tcid, LSTAT))) {
1003 if (ret == 1)
1004 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1005 else
1006 tst_resm(TEST_RESULT, test_msg);
1007 }
1008 else if (ret == 0)
1009 tst_resm(TEST_RESULT, test_msg);
1010 else if (cktcsid(tc_ptr->tcid, READLINK))
1011 do_readlink(tc_ptr);
1012 else if (cktcsid(tc_ptr->tcid, STAT))
1013 do_stat(tc_ptr);
1014 else if (cktcsid(tc_ptr->tcid, CHDIR))
1015 do_chdir(tc_ptr);
1016 else if (cktcsid(tc_ptr->tcid, LINK))
1017 do_link(tc_ptr);
1018 else if (cktcsid(tc_ptr->tcid, UNLINK))
1019 do_unlink(tc_ptr);
1020 else if (cktcsid(tc_ptr->tcid, CHMOD))
1021 do_chmod(tc_ptr);
1022 else if (cktcsid(tc_ptr->tcid, UTIME))
1023 do_utime(tc_ptr);
1024 else if (cktcsid(tc_ptr->tcid, RENAME))
1025 do_rename(tc_ptr);
1026 else if (cktcsid(tc_ptr->tcid, OPEN))
1027 do_open(tc_ptr);
1028 else
1029 tst_resm(TBROK, "Unknown test case processing actions declared");
1030 }
1031 }
1032 else
1033 tst_resm(TBROK, "Test Case Declaration Error");
1034 }
1035 return(0);
1036}
1037
1038/***********************************************************************
1039 * This routine checks for the return of EEXIST errno from requested
1040 * system call
1041 *
1042 * Argument is pointer to test_objects array of structures of type
1043 * all_test_cases
1044 ***********************************************************************/
1045void
1046do_EEXIST(tc_ptr)
1047struct all_test_cases *tc_ptr;
1048{
1049 if (cktcsid(tc_ptr->tcid, SYMLINK)) {
1050
1051 TEST( symlink(tc_ptr->fn_arg[0], tc_ptr->fn_arg[1]) );
1052 errno=TEST_ERRNO;
1053 if ((TEST_RETURN == -1) && (errno == EEXIST))
1054 if ( STD_FUNCTIONAL_TEST )
1055 tst_resm(TPASS, msgs[tc_ptr->pass_msg]);
1056 else
1057 Tst_count++;
1058 else
1059 tst_resm(TFAIL, "%s %s",
1060 "Expected EEXIST error when creating a symbolic link file",
1061 "which already existed");
1062 }
1063 else if (cktcsid(tc_ptr->tcid, MKDIR)) {
1064
1065 TEST ( mkdir(tc_ptr->fn_arg[1],MODE) );
1066 errno=TEST_ERRNO;
1067 if ((TEST_RETURN == -1) && (errno == EEXIST))
1068 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1069 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1070 else
1071 Tst_count++;
1072 else {
1073
1074 tst_resm(TFAIL, "%s %s",
1075 "Expected EEXIST error when creating a directory by a symbolic",
1076 "link file which pointed at no object file");
1077 rmdir(tc_ptr->fn_arg[1]);
1078 }
1079 }
1080 else if (cktcsid(tc_ptr->tcid, OPEN)) {
1081
1082 TEST( open(tc_ptr->fn_arg[1], (O_EXCL | O_CREAT)) )
1083 errno=TEST_ERRNO;
1084 if ((TEST_RETURN == -1) && (errno == EEXIST))
1085 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1086 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1087 else
1088 Tst_count++;
1089 else
1090 tst_resm(TFAIL, "%s %s errno:%d %s",
1091 "Expected EEXIST error for exclusively opening an object file",
1092 "through a symbolic link file was not received:",
1093 errno, strerror(errno));
1094 }
1095 else
1096 tst_resm(TBROK, "Unknown test case processing actions declared");
1097}
1098
1099/***********************************************************************
1100 * This routine checks for the return of ENOENT errno from requested
1101 * system call
1102 *
1103 * Argument is pointer to test_objects array of structures of type
1104 * all_test_cases
1105 ***********************************************************************/
1106void
1107do_ENOENT(tc_ptr)
1108struct all_test_cases *tc_ptr;
1109{
1110 if (cktcsid(tc_ptr->tcid, STAT)) {
1111
1112 if ((stat(tc_ptr->fn_arg[1], &asymlink) == -1) && (errno == ENOENT))
1113 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1114 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1115 else
1116 Tst_count++;
1117 else
1118 tst_resm(TFAIL, "%s %s errno:%d %s",
1119 "Expected ENOENT error for stating a non-existent directory",
1120 "through a symbolic link file was not received:",
1121 errno, strerror(errno));
1122 }
1123 else if (cktcsid(tc_ptr->tcid, CHDIR)) {
1124 if ((chdir(tc_ptr->fn_arg[1]) == -1) && (errno == ENOENT))
1125 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1126 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1127 else
1128 Tst_count++;
1129 else {
1130 tst_resm(TFAIL, "%s %s errno:%d %s",
1131 "Expected ENOENT error for changing to a non-existent",
1132 "directory through a symbolic link file was not received:",
1133 errno, strerror(errno));
1134 chdir(TESTDIR);
1135 }
1136 }
1137 else if (cktcsid(tc_ptr->tcid, LINK)) {
1138
1139 if ((link(tc_ptr->fn_arg[1], "nick") == -1) && (errno == ENOENT))
1140 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1141 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1142 else
1143 Tst_count++;
1144 else
1145 {
1146 tst_resm(TFAIL, "%s %s errno:%d %s",
1147 "Expected ENOENT error condition when link(2) a symbolic",
1148 "link which pointed at no object:", errno, strerror(errno));
1149 delete_files("nick", NULL);
1150 }
1151 }
1152 else if (cktcsid(tc_ptr->tcid, CHMOD)) {
1153
1154 if ((chmod(tc_ptr->fn_arg[1], MODE) == -1) && (errno == ENOENT))
1155 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1156 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1157 else
1158 Tst_count++;
1159 else
1160 tst_resm(TFAIL, "%s %s errno:%d %s",
1161 "Expected ENOENT error condition when chmod(2) a symbolic",
1162 "link which pointed at no object,", errno, strerror(errno));
1163 }
1164 else if (cktcsid(tc_ptr->tcid, UTIME)) {
1165
1166 if ((utime(tc_ptr->fn_arg[1], NULL) == -1) && (errno == ENOENT))
1167 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1168 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1169 else
1170 Tst_count++;
1171 else
1172 tst_resm(TFAIL, "%s %s errno:%d %s",
1173 "Expected ENOENT error condition when utime(2) a symbolic",
1174 "link which pointed at no object:", errno, strerror(errno));
1175 }
1176 else if (cktcsid(tc_ptr->tcid, OPEN)) {
1177
1178 if ((open(tc_ptr->fn_arg[1], O_RDWR) == -1) && (errno == ENOENT))
1179 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1180 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1181 else
1182 Tst_count++;
1183 else
1184 tst_resm(TFAIL, "%s %s errno:%d %s",
1185 "Expected ENOENT error for opening a non-existent object",
1186 " file through a symbolic link file was not received,",
1187 errno, strerror(errno));
1188 }
1189 else
1190 tst_resm(TBROK, "Unknown test case processing actions declared");
1191}
1192
1193/***********************************************************************
1194 * This routine checks for the return of ELOOP errno from requested
1195 * system call
1196 *
1197 * Argument is pointer to test_objects array of structures of type
1198 * all_test_cases
1199 ***********************************************************************/
1200void
1201do_ELOOP(tc_ptr)
1202struct all_test_cases *tc_ptr;
1203{
1204 if (cktcsid(tc_ptr->tcid, STAT)) {
1205
1206 TEST( stat(tc_ptr->fn_arg[1], &asymlink) );
1207 errno=TEST_ERRNO;
1208 if ((TEST_RETURN == -1) && (errno == ELOOP))
1209 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1210 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1211 else
1212 Tst_count++;
1213 else
1214 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1215 tst_resm(TEST_RESULT, "%s errno:%d %s",
1216 "Expected ELOOP errno from stat(2) (nested symb link),",
1217 errno, strerror(errno));
1218 else
1219 Tst_count++;
1220 }
1221 else if (cktcsid(tc_ptr->tcid, CHDIR)) {
1222
1223 TEST( chdir(tc_ptr->fn_arg[1]) );
1224 errno=TEST_ERRNO;
1225 if ((TEST_RETURN == -1) && (errno == ELOOP))
1226 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1227 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1228 else
1229 Tst_count++;
1230 else {
1231
1232 tst_resm(TFAIL, "%s errno:%d %s",
1233 "Expected ELOOP error condition when chdir(2) a nested symbolic link:",
1234 errno, strerror(errno));
1235 chdir(TESTDIR);
1236 }
1237 }
1238 else if (cktcsid(tc_ptr->tcid, LINK)) {
1239
1240 TEST ( link(tc_ptr->fn_arg[1], O_FILE) );
1241 errno=TEST_ERRNO;
1242 if ((TEST_RETURN == -1) && (errno == ELOOP))
1243 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1244 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1245 else
1246 Tst_count++;
1247 else
1248 tst_resm(TFAIL, "%s errno:%d %s",
1249 "Expected ELOOP error condition when link(2) a nested symbolic link:",
1250 errno, strerror(errno));
1251 }
1252 else if (cktcsid(tc_ptr->tcid, CHMOD)) {
1253
1254 TEST ( chmod(tc_ptr->fn_arg[1], MODE) );
1255 errno=TEST_ERRNO;
1256 if ((TEST_RETURN == -1) && (errno == ELOOP))
1257 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1258 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1259 else
1260 Tst_count++;
1261 else
1262 tst_resm(TFAIL, "%s errno:%d %s",
1263 "Expected ELOOP error condition when chmod(2) a nested symbolic link:",
1264 errno, strerror(errno));
1265 return;
1266 }
1267 else if (cktcsid(tc_ptr->tcid, UTIME)) {
1268
1269 TEST( utime(tc_ptr->fn_arg[1], NULL) );
1270 errno=TEST_ERRNO;
1271
1272 if ((TEST_RETURN == -1) && (errno == ELOOP))
1273 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1274 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1275 else
1276 Tst_count++;
1277 else
1278 tst_resm(TFAIL, "%s errno:%d %s",
1279 "Expected ELOOP error condition when utime(2) a nested symbolic link:",
1280 errno, strerror(errno));
1281 }
1282 else if (cktcsid(tc_ptr->tcid, OPEN)) {
1283
1284 int fd;
1285 TEST( open(tc_ptr->fn_arg[1], O_CREAT) );
1286 fd=TEST_RETURN;
1287 errno=TEST_ERRNO;
1288 if ((fd == -1) && (errno == ELOOP))
1289 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1290 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1291 else
1292 Tst_count++;
1293 else
1294 tst_resm(TFAIL, "%s errno:%d %s",
1295 "Expected ELOOP error condition when open(2) a nested symbolic link:",
1296 errno, strerror(errno));
1297 }
1298 else
1299 tst_resm(TBROK, "Unknown test case processing actions declared");
1300}
1301
1302/***********************************************************************
1303 * This routine checks for the return of ENOTDIR errno from requested
1304 * system call
1305 *
1306 * Argument is pointer to test_objects array of structures of type
1307 * all_test_cases
1308 ***********************************************************************/
1309void
1310do_ENOTDIR(tc_ptr)
1311struct all_test_cases *tc_ptr;
1312{
1313 if (cktcsid(tc_ptr->tcid, RMDIR)) {
1314
1315 TEST( mkdir(tc_ptr->fn_arg[0], MODE) );
1316 errno=TEST_ERRNO;
1317 if (TEST_RETURN == -1)
1318 tst_resm(TBROK, "mkdir(2) Failure when creating %s",
1319 tc_ptr->fn_arg[0]);
1320 else if ((rmdir(tc_ptr->fn_arg[1]) == -1) && (errno == ENOTDIR)) {
1321
1322 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1323 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1324 else
1325 Tst_count++;
1326 rmdir(tc_ptr->fn_arg[0]);
1327 }
1328 else
1329 tst_resm(TFAIL, "%s %s errno:%d %s",
1330 "Expected ENOTDIR error for removing a non-existent",
1331 "directory through a symbolic link file was not received,",
1332 errno, strerror(errno));
1333 }
1334 else
1335 tst_resm(TBROK, "Unknown test case processing actions declared");
1336}
1337
1338/***********************************************************************
1339 * This routine checks for the return of EXDEV errno from requested
1340 * system call
1341 *
1342 * Argument is pointer to test_objects array of structures of type
1343 * all_test_cases
1344 ***********************************************************************/
1345void
1346do_EXDEV(tc_ptr)
1347struct all_test_cases *tc_ptr;
1348{
1349 if (cktcsid(tc_ptr->tcid, RENAME)) {
1350
1351 TEST( rename(tc_ptr->fn_arg[1], Y_A_S_FILE) );
1352 errno=TEST_ERRNO;
1353 if ((TEST_RETURN == -1) && (errno == EXDEV)) {
1354 if (see_if_a_symlink(Y_A_S_FILE) == -1)
1355 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1356 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1357 else
1358 Tst_count++;
1359 else
1360 tst_resm(TFAIL, "%s %s %s file outside of current file system",
1361 "rename(3) returned -1 when trying to move symbolic link file",
1362 "outside of current file system, but created", Y_A_S_FILE);
1363 }
1364 else {
1365 tst_resm(TFAIL, "%s %s errno:%d %s",
1366 "Expected EXDEV error for renaming an existing symbolic",
1367 "link file to a location outside of existing file system,",
1368 errno, strerror(errno));
1369 delete_files("/NiCkEr", NULL);
1370 }
1371 }
1372 else
1373 tst_resm(TBROK, "Unknown test case processing actions declared");
1374}
1375
1376/***********************************************************************
1377 * This routine checks for the return of ENAMETOOLONG errno from requested
1378 * system call
1379 *
1380 * Argument is pointer to test_objects array of structures of type
1381 * all_test_cases
1382 ***********************************************************************/
1383void
1384do_ENAMETOOLONG(tc_ptr)
1385struct all_test_cases *tc_ptr;
1386{
1387 int ret;
1388
1389 if (cktcsid(tc_ptr->tcid, SYMLINK)) {
1390
1391 TEST( symlink(tc_ptr->fn_arg[0], full_path) );
1392 errno=TEST_ERRNO;
1393 if ((TEST_RETURN == -1) && (errno == ENAMETOOLONG))
1394 if (see_if_a_symlink(full_path) == -1)
1395 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1396 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1397 else
1398 Tst_count++;
1399 else
1400 tst_resm(TFAIL, "%s %s %d %s",
1401 "symlink(2) returned -1 when trying to create a symbolic",
1402 "link file whose name exceeded", (PATH_MAX+1),
1403 "characters, but it created the symbolic link file");
1404 else
1405 tst_resm(TFAIL,
1406 "Expected ENAMETOOLONG error when creating %s symbolic link file with a path exceeding %d characters: errno:%d %s",
1407 tc_ptr->fn_arg[1], (PATH_MAX+1), errno, strerror(errno));
1408 }
1409 else if (cktcsid(tc_ptr->tcid, READLINK)) {
1410
1411 char scratch[PATH_MAX+1];
1412
1413 ret=readlink(full_path, scratch, strlen(full_path));
1414 if (( ret == -1) && (errno == ENAMETOOLONG))
1415 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1416 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1417 else
1418 Tst_count++;
1419 else
1420 tst_resm(TFAIL,
1421 "Expected ENAMETOOLONG error when reading %s symbolic link file with a path exceeding %d characters: errno:%d %s",
1422 tc_ptr->fn_arg[1], (PATH_MAX+1), errno, strerror(errno));
1423 }
1424 else
1425 tst_resm(TBROK, "Unknown test case processing actions declared");
1426}
1427
1428/***********************************************************************
1429 * This routine checks for the return of EINVAL errno from requested
1430 * system call
1431 *
1432 * Argument is pointer to test_objects array of structures of type
1433 * all_test_cases
1434 ***********************************************************************/
1435void
1436do_EINVAL(tc_ptr)
1437struct all_test_cases *tc_ptr;
1438{
1439 if (cktcsid(tc_ptr->tcid, READLINK)) {
1440 TEST( readlink(tc_ptr->fn_arg[0], test_msg, BUFMAX) );
1441 errno=TEST_ERRNO;
1442 if (TEST_RETURN == -1) {
1443 if (errno == EINVAL) {
1444 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1445 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1446 else
1447 Tst_count++;
1448 } else
1449 tst_resm(TFAIL, "readlink(2) ret:-1, errno:%d, : Exp errno:%d",
1450 errno, EINVAL);
1451 }
1452 else {
1453 tst_resm(TFAIL, "readlink(2) did not returned -1 when reading %s",
1454 "a file which is not a symbolic link file");
1455 }
1456 }
1457 else
1458 tst_resm(TBROK, "Unknown test case processing actions declared");
1459}
1460
1461/***********************************************************************
1462 * This routine checks out the readlink(2) system call for a successful
1463 * invocation
1464 *
1465 * Argument is pointer to test_objects array of structures of type
1466 * all_test_cases
1467 ***********************************************************************/
1468void
1469do_readlink(tc_ptr)
1470struct all_test_cases *tc_ptr;
1471{
1472 char scratch[PATH_MAX];
1473 int ret;
1474
1475 ret=readlink(tc_ptr->fn_arg[1], scratch, strlen(tc_ptr->fn_arg[0]));
1476
1477 /*** the TEST macro cannot be used here for some reason ****/
1478
1479 if (ret == -1) {
1480 tst_resm(TFAIL,
1481 "readlink(2) failure on %s symbolic link file",
1482 tc_ptr->fn_arg[1]);
1483
1484 }
1485 else if (strncmp(tc_ptr->fn_arg[0], scratch,
1486 strlen(tc_ptr->fn_arg[0])) != 0) {
1487
1488 /* Must null terminate scratch because readlink(2) doesn't */
1489
1490 scratch[strlen(tc_ptr->fn_arg[0])] = '\0';
1491
1492 tst_resm(TFAIL,
1493 "readlink(2) Error : Expected %s symbolic link file contents but %s actual contents were returned",
1494 tc_ptr->fn_arg[0], scratch);
1495 }
1496 else if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1497 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1498 else
1499 Tst_count++;
1500}
1501
1502/***********************************************************************
1503 * This routine checks out the stat(2) system call for a successful
1504 * invocation
1505 *
1506 * Argument is pointer to test_objects array of structures of type
1507 * all_test_cases
1508 ***********************************************************************/
1509void
1510do_stat(tc_ptr)
1511struct all_test_cases *tc_ptr;
1512{
1513 if (statter.st_dev != asymlink.st_dev)
1514 tst_resm(TFAIL,
1515 "stat of symbolic link reference to object device info %ld != stat of object file device info %ld",
1516 statter.st_dev, asymlink.st_dev);
1517
1518 else if (statter.st_mode != asymlink.st_mode)
1519 tst_resm(TFAIL,
1520 "stat of symbolic link reference to object file permissions %ld != stat of object file permissions %ld",
1521 statter.st_mode, asymlink.st_mode);
1522
1523 else if (statter.st_nlink != asymlink.st_nlink)
1524 tst_resm(TFAIL,
1525 "stat of symbolic link reference to object file link count %ld != stat of object file link count %ld",
1526 statter.st_nlink, asymlink.st_nlink);
1527
1528 else if (statter.st_uid != asymlink.st_uid)
1529 tst_resm(TFAIL,
1530 "stat of symbolic link reference to object file uid %ld != stat of object file uid %ld",
1531 statter.st_uid, asymlink.st_uid);
1532
1533 else if (statter.st_gid != asymlink.st_gid)
1534 tst_resm(TFAIL,
1535 "stat of symbolic link reference to object file gid %ld != stat of object file gid %ld",
1536 statter.st_gid, asymlink.st_gid);
1537
1538 else if (statter.st_size != asymlink.st_size)
1539 tst_resm(TFAIL,
1540 "stat of symbolic link reference to object file size %ld != stat of object file size %ld",
1541 statter.st_size, asymlink.st_size);
1542
1543 else if (statter.st_atime != asymlink.st_atime)
1544 tst_resm(TFAIL,
1545 "stat of symbolic link reference to object access time %ld != stat of object file access time %ld",
1546 statter.st_atime, asymlink.st_atime);
1547
1548 else if (statter.st_mtime != asymlink.st_mtime)
1549 tst_resm(TFAIL,
1550 "stat of symbolic link reference to object modify time %ld != stat of object file modify time %ld",
1551 statter.st_atime, asymlink.st_atime);
1552
1553 else if (statter.st_ctime != asymlink.st_ctime)
1554 tst_resm(TFAIL,
1555 "stat of symbolic link reference to object change time %ld != stat of object file change time %ld",
1556 statter.st_atime, asymlink.st_atime);
1557 else if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1558 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1559 else
1560 Tst_count++;
1561}
1562
1563/***********************************************************************
1564 * This routine checks out the chdir(2) system call for a successful
1565 * invocation
1566 *
1567 * Argument is pointer to test_objects array of structures of type
1568 * all_test_cases
1569 ***********************************************************************/
1570void
1571do_chdir(tc_ptr)
1572struct all_test_cases *tc_ptr;
1573{
1574 if (mkdir(tc_ptr->fn_arg[2],MODE) == -1)
1575 tst_resm(TFAIL, "Could not create a setup directory file");
1576 else {
1577
1578 sprintf(Buf, "mkdir(%s, %#o) was successful\n", tc_ptr->fn_arg[2],MODE);
1579 strcat(Buffer, Buf);
1580
1581 if (chdir(tc_ptr->fn_arg[1]) == -1)
1582 tst_resm(TFAIL, "%sCould not change a directory file through a %s",
1583 Buffer, "symbolic link which which pointed at object");
1584 else {
1585
1586 char *cwd, *getcwd();
1587 char expected_location[PATH_MAX];
1588 /*
1589 * Build expected current directory position
1590 */
1591 strcpy(expected_location, TESTDIR);
1592 strcat(expected_location, "/");
1593 strcat(expected_location, tc_ptr->fn_arg[2]);
1594
1595 if ((cwd = getcwd((char *)NULL, 64)) == NULL)
1596 tst_resm(TFAIL, "getcwd(3) FAILURE");
1597 else if (strcmp(cwd, expected_location) == 0)
1598 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1599 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1600 else
1601 Tst_count++;
1602 else {
1603 tst_resm(TFAIL, "%s%s %s %s not equal to expected %s", Buffer,
1604 "chdir(2) returned successfully, but getcwd(3) indicated",
1605 "new current working directory location", cwd, expected_location);
1606 }
1607 chdir(TESTDIR);
1608 }
1609 rmdir(tc_ptr->fn_arg[2]);
1610 }
1611}
1612
1613/***********************************************************************
1614 * This routine checks out the link(2) system call for a successful
1615 * invocation
1616 *
1617 * Argument is pointer to test_objects array of structures of type
1618 * all_test_cases
1619 ***********************************************************************/
1620void
1621do_link(tc_ptr)
1622struct all_test_cases *tc_ptr;
1623{
1624 struct stat stbuf;
1625
1626 if (link(tc_ptr->fn_arg[1], "nick") == -1) {
1627 tst_resm(TFAIL, "%slink(%s, \"nick\") failed, errno: %d\n%s %s",
1628 Buffer, tc_ptr->fn_arg[1], errno,
1629 "link of new file to object file via symbolic link file failed",
1630 "when expected not to");
1631 }
1632 else {
1633 sprintf(Buf, "link(%s, \"nick\") was successful\n", tc_ptr->fn_arg[1]);
1634 strcat(Buffer, Buf);
1635
1636 if ( STD_FUNCTIONAL_TEST ) {
1637 /*
1638 * Check that links counts were properly set
1639 */
1640 if (lstat(tc_ptr->fn_arg[1], &asymlink) == -1) {
1641 tst_resm(TBROK, "lstat(%s) failed. errno: %d",
1642 tc_ptr->fn_arg[1], errno);
1643
1644 } else if (lstat("nick", &statter) == -1) {
1645 tst_resm(TBROK, "lstat(nick) failed, errno:%d", errno);
1646 } else {
1647 if (statter.st_ino == asymlink.st_ino) {
1648 if ((statter.st_nlink ==2) && (asymlink.st_nlink == 2)) {
1649 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1650 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1651 else
1652 Tst_count++;
1653 } else {
1654 lstat(tc_ptr->fn_arg[2], &stbuf);
1655
1656 tst_resm(TFAIL,
1657 "%slink(%s, %s) failed to adjust link count.\n\
1658 count for nick is %d, count for %s is %d, count for %s is %d.",
1659 Buffer, tc_ptr->fn_arg[1], "nick",
1660 statter.st_nlink, tc_ptr->fn_arg[1], asymlink.st_nlink,
1661 tc_ptr->fn_arg[2], stbuf.st_nlink);
1662 }
1663 } else {
1664 tst_resm(TFAIL,
1665 "%sA lstat of %s (ino:%d) and of\n\t\t\
1666%s (ino:%d), does not show them being the same ino.", Buffer,
1667 tc_ptr->fn_arg[1], asymlink.st_ino, "nick", statter.st_ino);
1668 }
1669 }
1670 }
1671 delete_files("nick", NULL);
1672 }
1673}
1674
1675/***********************************************************************
1676 * This routine checks out the unlink(2) system call for a successful
1677 * invocation
1678 *
1679 * Argument is pointer to test_objects array of structures of type
1680 * all_test_cases
1681 ***********************************************************************/
1682void
1683do_unlink(tc_ptr)
1684struct all_test_cases *tc_ptr;
1685{
1686 if (stat(tc_ptr->fn_arg[2], &asymlink) == -1)
1687 tst_resm(TBROK,
1688 "stat(2) Failure when accessing %s object file", tc_ptr->fn_arg[2]);
1689 else if (unlink(tc_ptr->fn_arg[1]) == -1)
1690 tst_resm(TFAIL, "unlink(2) failed when removing symbolic link file");
1691 else {
1692 sprintf(Buf, "unlink(%s) was successful\n", tc_ptr->fn_arg[1]);
1693 strcat(Buffer, Buf);
1694 if (stat(tc_ptr->fn_arg[2], &statter) == -1)
1695 tst_resm(TFAIL,"%s %s",
1696 "unlink(2) failed because it not only removed symbolic link",
1697 "file which pointed at object file, but object file as well");
1698
1699 else
1700 if ((statter.st_ino == asymlink.st_ino) &&
1701 (statter.st_dev == asymlink.st_dev) &&
1702 (statter.st_size == asymlink.st_size))
1703
1704 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1705 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1706 else
1707 Tst_count++;
1708 else
1709 tst_resm(TFAIL, "%s%s %s %s", Buffer,
1710 "unlink(2) failed because it not only removed symbolic link",
1711 "file which pointed at object file, but it changed object",
1712 "file inode information");
1713 }
1714
1715}
1716
1717/***********************************************************************
1718 * This routine checks out the chmod(2) system call for a successful
1719 * invocation
1720 *
1721 * Argument is pointer to test_objects array of structures of type
1722 * all_test_cases
1723 ***********************************************************************/
1724void
1725do_chmod(tc_ptr)
1726struct all_test_cases *tc_ptr;
1727{
1728 if (stat(tc_ptr->fn_arg[2], &asymlink) == -1)
1729 tst_resm(TBROK,
1730 "stat(2) Failure when accessing %s object file", tc_ptr->fn_arg[2]);
1731 else if (chmod(tc_ptr->fn_arg[1], (MODE | MASK)) == -1)
1732 tst_resm(TFAIL, "%s%s %s", Buffer,
1733 "chmod(2) failed when changing file permission",
1734 "through symbolic link file");
1735 else {
1736 sprintf(Buf, "chmod(%s, %#o) was successful\n", tc_ptr->fn_arg[1],
1737 (MODE | MASK));
1738 strcat(Buffer, Buf);
1739
1740 if (stat(tc_ptr->fn_arg[2], &statter) == -1)
1741 tst_resm(TBROK,
1742 "stat(2) Failure when accessing %s object file", tc_ptr->fn_arg[2]);
1743 else
1744 if ((statter.st_mode == (MODE | MASK)) &&
1745 (statter.st_mode != asymlink.st_mode))
1746 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1747 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1748 else
1749 Tst_count++;
1750 else
1751 tst_resm(TFAIL, "%s%s %o to %o %s", Buffer,
1752 "chmod(2) failed to change object file permissions from",
1753 asymlink.st_mode, (MODE | MASK),
1754 "through symbolic link file");
1755 }
1756
1757}
1758
1759/***********************************************************************
1760 * This routine checks out the utime(2) system call for a successful
1761 * invocation
1762 *
1763 * Argument is pointer to test_objects array of structures of type
1764 * all_test_cases
1765 ***********************************************************************/
1766void
1767do_utime(tc_ptr)
1768struct all_test_cases *tc_ptr;
1769{
1770 struct utimbuf utimes;
1771
1772 if (stat(tc_ptr->fn_arg[2], &asymlink) == -1)
1773 tst_resm(TBROK, "stat(2) Failure when accessing %s object file",
1774 tc_ptr->fn_arg[2]);
1775 else {
1776 /* Now add a few values to access and modify times */
1777
1778 utimes.actime = asymlink.st_atime + a_time_value;
1779 utimes.modtime = asymlink.st_mtime + a_time_value;
1780
1781 /* Now hand off to utime(2) via symbolic link file*/
1782
1783 if (utime(tc_ptr->fn_arg[1], &utimes) == -1)
1784 tst_resm(TFAIL, "%s %s",
1785 "utime(2) failed to process object file access and modify",
1786 "time updates through symbolic link");
1787 else {
1788 /* Now verify changes were made */
1789
1790 if (stat(tc_ptr->fn_arg[2], &statter) == -1)
1791 tst_resm(TBROK,
1792 "stat(2) Failure when accessing %s object file",
1793 tc_ptr->fn_arg[2]);
1794 else {
1795 time_t temp, diff;
1796
1797 temp = statter.st_atime - asymlink.st_atime;
1798 diff = (statter.st_mtime - asymlink.st_mtime) - temp;
1799
1800 if (! diff)
1801 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1802 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1803 else
1804 Tst_count++;
1805 else
1806 tst_resm(TFAIL, "%s %s %d greater than original times",
1807 "utime(2) failed to change object file access and",
1808 "modify times through symbolic link to a value",
1809 a_time_value);
1810 }
1811 }
1812 }
1813}
1814
1815/***********************************************************************
1816 * This routine checks out the rename(2) system call for a successful
1817 * invocation
1818 *
1819 * Argument is pointer to test_objects array of structures of type
1820 * all_test_cases
1821 ***********************************************************************/
1822void
1823do_rename(tc_ptr)
1824struct all_test_cases *tc_ptr;
1825{
1826 int pts_at_object = 0;
1827
1828
1829 if (stat(tc_ptr->fn_arg[2], &statter) != -1)
1830 pts_at_object=1;
1831
1832 TEST (rename(tc_ptr->fn_arg[1], A_S_FILE) );
1833 errno=TEST_ERRNO;
1834 if (TEST_RETURN == -1)
1835 tst_resm(TFAIL, "rename(3) failed to rename %s symbolic link file to %s",
1836 tc_ptr->fn_arg[2], A_S_FILE);
1837 else if (pts_at_object)
1838 if (ck_both(tc_ptr->fn_arg[0], A_S_FILE, tc_ptr->fn_arg[2]))
1839 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1840 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1841 else
1842 Tst_count++;
1843 else
1844 tst_resm(TFAIL, test_msg);
1845 else if ( ! ck_symlink(tc_ptr->fn_arg[0], A_S_FILE, NULL))
1846 tst_resm(TFAIL, test_msg);
1847 else if (stat(tc_ptr->fn_arg[1], &asymlink) != -1)
1848 tst_resm(TFAIL,
1849 "rename(3) did not remove %s when renaming to %s",
1850 tc_ptr->fn_arg[1], A_S_FILE);
1851 else if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1852 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1853 else
1854 Tst_count++;
1855}
1856
1857/***********************************************************************
1858 * This routine checks out the open(2) system call for a successful
1859 * invocation
1860 *
1861 * Argument is pointer to test_objects array of structures of type
1862 * all_test_cases
1863 ***********************************************************************/
1864void
1865do_open(tc_ptr)
1866struct all_test_cases *tc_ptr;
1867{
1868 int fd = -1;
1869 int ret, pts_at_object = 0;
1870 char scratch[PATH_MAX];
1871
1872
1873 if (stat(tc_ptr->fn_arg[2], &statter) != -1)
1874 pts_at_object=1;
1875
1876 if (pts_at_object) {
1877 TEST( open(tc_ptr->fn_arg[1], O_RDWR) );
1878 errno=TEST_ERRNO;
1879 if ((fd=TEST_RETURN) == -1) {
1880 tst_resm(TFAIL,
1881 "open(2) Failure when opening object file through symbolic link file");
1882 return;
1883 }
1884 }
1885 else {
1886 TEST(open(tc_ptr->fn_arg[1], (O_CREAT | O_RDWR), MODE) );
1887 errno=TEST_ERRNO;
1888 if ((fd=TEST_RETURN) == -1) {
1889 tst_resm(TFAIL,
1890 "open(2) Failure when creating object file through symbolic link file");
1891 return;
1892 }
1893 }
1894 if ((ret=write(fd, BIG_STRING, strlen(BIG_STRING))) == -1) {
1895 tst_resm(TFAIL,
1896 "write(2) Failure to object file opened through a symbolic link file: errno:%d",
1897 errno);
1898 }
1899 else if (ret != strlen(BIG_STRING)) {
1900 tst_resm(TFAIL,
1901 "write(2) Failed to write %d bytes to object file opened through a symbolic link file",
1902 strlen(BIG_STRING));
1903 }
1904 else if (lseek(fd, 0L, 0) == -1) {
1905 tst_resm(TFAIL,
1906 "lseek(2) Failed to position to beginning of object file opened through a symbolic link file: errno = %d",
1907 errno);
1908 }
1909 else if ((ret=read(fd, scratch, strlen(BIG_STRING))) == -1) {
1910 tst_resm(TFAIL,
1911 "read(2) Failure of object file opened through a symbolic link file: errno = %d",
1912 errno);
1913 }
1914 else if (ret != strlen(BIG_STRING)) {
1915 tst_resm(TFAIL,
1916 "read(2) Failed to read %d bytes to object file opened through a symbolic link file",
1917 strlen(BIG_STRING));
1918 }
1919 else if (strncmp(BIG_STRING, scratch, strlen(BIG_STRING)) != 0) {
1920 tst_resm(TFAIL,
1921 "Content of write(2) and read(2) Failed to object file through symbolic link file was not as expected. Expected %s and read returned %s",
1922 BIG_STRING, scratch);
1923 }
1924 else {
1925 /*
1926 * Close off symbolic link file to object file access
1927 */
1928 if (close(fd) == -1) {
1929 tst_resm(TFAIL,
1930 "close(2) Failure when closing object file accessed symbolic link file");
1931 }
1932 /*
1933 * Now, lets open up and read object file and compare contents
1934 */
1935 else if ((fd=open(tc_ptr->fn_arg[0], O_RDONLY)) == -1) {
1936 tst_resm(TFAIL, "open(2) Failure when opening %s file: errno:%d %s",
1937 tc_ptr->fn_arg[0], errno, strerror(errno));
1938 }
1939 else if ((ret=read(fd, scratch, strlen(BIG_STRING))) == -1) {
1940 tst_resm(TFAIL,
1941 "read(2) Failure of object file opened through a symbolic link file: errno:%d", errno);
1942 }
1943 else if (ret != strlen(BIG_STRING)) {
1944 tst_resm(TFAIL,
1945 "read(2) Failed to read %d bytes to object file opened through a symbolic link file",
1946 strlen(BIG_STRING));
1947 }
1948 else if (strncmp(BIG_STRING, scratch, strlen(BIG_STRING)) != 0) {
1949 tst_resm(TFAIL,
1950 "Content of write(2) and read(2) Failed to object file through symbolic link file was not as expected. Expected %s and read returned %s",
1951 BIG_STRING, scratch);
1952 }
1953 else if (pts_at_object) {
1954 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1955 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1956 else
1957 Tst_count++;
1958 }
1959 else { /* Insure newly created object file is pointed at */
1960 if (ck_both(tc_ptr->fn_arg[0], tc_ptr->fn_arg[1], tc_ptr->fn_arg[0]))
1961 if ( TEST_RESULT != TPASS || STD_FUNCTIONAL_TEST )
1962 tst_resm(TEST_RESULT, msgs[tc_ptr->pass_msg]);
1963 else
1964 Tst_count++;
1965 else
1966 tst_resm(TFAIL, test_msg);
1967 }
1968 close(fd);
1969 }
1970}
1971
1972/***************************************************************
1973 * setup() - performs all ONE TIME setup for this test.
1974 ***************************************************************/
1975void
1976setup()
1977{
1978 /* capture signals */
1979 tst_sig(FORK, DEF_HANDLER, cleanup);
1980
1981 /* create a temporary directory and go to it */
1982 tst_tmpdir();
1983
1984 /* Pause if that option was specified */
1985 TEST_PAUSE;
1986
1987} /* End setup() */
1988
1989
1990/***************************************************************
1991 * cleanup() - performs all ONE TIME cleanup for this test at
1992 * completion or premature exit.
1993 ***************************************************************/
1994void
1995cleanup()
1996{
1997 /*
1998 * print timing stats if that option was specified.
1999 */
2000 TEST_CLEANUP;
2001
2002 /* remove temporary directory and all files in it. */
2003 tst_rmdir();
2004
2005 /* exit with return code appropriate for results */
2006 tst_exit();
2007
2008} /* End cleanup() */
2009
2010
2011/*
2012 *
2013 */
nstraz94181082000-08-30 18:43:38 +00002014void help()
alaffin00657852000-07-27 17:26:25 +00002015{
2016 int ind;
2017
nstraz94181082000-08-30 18:43:38 +00002018 printf(" -T id Determines which tests cases to execute:\n");
alaffin00657852000-07-27 17:26:25 +00002019
2020 for (ind=0; ind<sizeof(all_tcses)/sizeof(struct tcses ); ind++) {
nstraz94181082000-08-30 18:43:38 +00002021 printf(" %s/%s - %s\n", all_tcses[ind].tcid, all_tcses[ind].syscall,
alaffin00657852000-07-27 17:26:25 +00002022 all_tcses[ind].desc);
2023 }
2024}