blob: 91190f705949b652b8e0cd957efab63cc7e02198 [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 */
alaffin81a90652000-07-31 22:41:24 +000032/* $Id: symlink01.c,v 1.2 2000/07/31 22:41:24 alaffin 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[] = {
399 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
439};
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
501int Help = 0;
502char *Tcid = NULL;
503
504option_t Options[] = {
505 { "h", &Help, NULL }, /* -h option */
506 { "T:", NULL, &Tcid }, /* -T tcid option */
507 { NULL, NULL, NULL }
508};
509
510/***********************************************************************
511 * MAIN
512 ***********************************************************************/
513main(argc, argv)
514int argc;
515char *argv[];
516{
517 int ctr, tc_ctr;
518 char *ptr;
519 struct all_test_cases *tc_ptr;
520 struct tcses *tcs_ptr, *get_tcs_info();
521 int do_syscalltests();
522 void cleanup();
523 int lc; /* loop counter */
524 char *msg; /* message returned from parse_opts */
525
526
527 /***************************************************************
528 * parse standard options, and exit if there is an error
529 ***************************************************************/
530 if ( (msg=parse_opts(argc, argv, Options)) != (char *) NULL ) {
531 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
532 tst_exit();
533 }
534
535 /*
536 * If the -T option was used, use that TCID or use the default
537 */
538 if ( Tcid != NULL ) {
539 TCID = Tcid;
540 Selectedtests=Tcid;
541
542 }
543#ifndef ALL
544 else {
545 TCID = DEFAULT_TCID;
546 Selectedtests = DEFAULT_TCID;
547 }
548#endif
549
550 if ( Help ) {
551 printf("Usage %s %s[-h][-T tcid]\n", argv[0], STD_opts());
552 help();
553 exit(0);
554 }
555
556 /*
557 * Get test case specification information and assign TST_TOTAL
558 */
559 if ((tcs_ptr=get_tcs_info(Selectedtests)) == NULL) {
560 TST_TOTAL=1;
561 tst_brkm(TBROK, cleanup,
562 "Unknown symbolic link test case specification executed");
563 }
564
565 /***************************************************************
566 * perform global setup for test
567 ***************************************************************/
568
569 setup();
570
571 /***************************************************************
572 * check looping state if -c option given
573 ***************************************************************/
574 for (lc=0; TEST_LOOPING(lc); lc++) {
575
576 /* reset Tst_count in case we are looping. */
577 Tst_count=0;
578
579 /*
580 * Execute tcs testing function and all defined test cases
581 */
582 do_syscalltests(tcs_ptr);
583
584 } /* End for TEST_LOOPING */
585
586 /*
587 * End appropriately
588 */
589 cleanup();
590}
591
592/***********************************************************************
593 * This function maps the name of the process to a test case specification
594 * defined in the all_tcses array of tcses structures. Either a pointer
595 * to the mapped test case specification information is returned or a
596 * null pointer.
597 *
598 * Argument is path to program name.
599 ***********************************************************************/
600struct tcses *get_tcs_info(ptr)
601char *ptr;
602{
603 int ctr;
604 struct tcses *tcs_ptr, temp;
605
606#if ALL
607 if ( ptr == NULL ) {
608
609 TST_TOTAL=0;
610 for (ctr=1; ctr < sizeof(all_tcses)/sizeof(struct tcses); ctr++)
611 TST_TOTAL += all_tcses[ctr].test_cases;
612 return all_tcses;
613 }
614#endif
615
616
617 for(ctr=0; ctr < (sizeof(all_tcses)/sizeof(struct tcses)); ctr++) {
618 if ( strcmp(ptr, all_tcses[ctr].tcid) == 0 ||
619 strcmp(ptr, all_tcses[ctr].syscall) == 0 ) {
620 tcs_ptr = &all_tcses[ctr];
621 TCID = all_tcses[ctr].tcid;
622 TST_TOTAL=tcs_ptr->test_cases;
623 return(tcs_ptr);
624 }
625
626 }
627 return(NULL);
628}
629
630/***********************************************************************
631 * Determines if what path points at is a symbolic link file
632 *
633 * Argument is path to symbolic link file.
634 *
635 * Return status is one if a symbolic link file. Zero if not a symbolic
636 * link file and a minus one if the path doesn't point at a file.
637 ***********************************************************************/
638see_if_a_symlink(path)
639char *path;
640{
641 if (lstat(path, &asymlink) < 0)
642 return(-1);
643
644 if ((asymlink.st_mode & S_IFMT) == S_IFLNK)
645 return(1);
646 else
647 return(0);
648}
649
650/***********************************************************************
651 * This function performs without any hesitation, file(s) deletions
652 ***********************************************************************/
653void
654delete_files(path1, path2)
655char *path1, *path2;
656{
657 unlink(path1);
658 unlink(path2);
659}
660
661/***********************************************************************
662 *
663 * This routine creates a symbolic link file.
664 *
665 * Argument one is symbolic link pathname to point at.
666 * Argument two is name of symbolic link file.
667 *
668 ***********************************************************************/
669creat_symlink(path1, path2)
670char *path1, *path2;
671{
672 TEST( symlink(path1, path2) );
673 errno=TEST_ERRNO;
674 if (TEST_RETURN == -1) {
675 TEST_RESULT=TBROK;
676 sprintf(test_msg,
677 "symlink(2) Failure when creating setup %s object file: errno:%d %s",
678 path1, errno, strerror(errno));
679 return(0);
680 }
681 else {
682 sprintf(Buf, "symlink(%s, %s) was succesful.\n", path1, path2);
683 strcat(Buffer, Buf);
684#if DEBUG
685 tst_resm(TPASS, "symlink(%s, %s) was succesful.", path1, path2);
686#endif
687 }
688 return(1);
689}
690
691/***********************************************************************
692 *
693 * This routine creates a regular file.
694 *
695 * Argument one is a pathname
696 *
697 ***********************************************************************/
698creat_object(path1)
699char *path1;
700{
701 int fd;
702 if ((fd=creat(path1, MODE)) == -1) {
703 TEST_RESULT=TBROK;
704 sprintf(test_msg,
705 "creat(2) Failure when creating setup %s object file: errno:%d %s",
706 path1, errno, strerror(errno));
707 return(0);
708 }
709 else {
710 sprintf(Buf, "creat(%s, %#o) was succesful.\n", path1, MODE);
711 strcat(Buffer, Buf);
712#if DEBUG
713 tst_resm(TPASS, "creat(%s, %#o) was succesful.", path1, MODE);
714#endif
715 }
716 if (close(fd) == -1) {
717 TEST_RESULT=TBROK;
718 sprintf(test_msg,
719 "close(2) Failure when closing setup %s object file: errno:%d %s",
720 path1, errno, strerror(errno));
721 return(0);
722 }
723 return(1);
724}
725
726/***********************************************************************
727 *
728 * This routine creates a symbolic link file and a regular file.
729 *
730 * Argument one is a pathname of object file
731 * Argument two is symbolic link file name
732 * Argument three is regular file name
733 *
734 ***********************************************************************/
735creat_both(path1, path2, path3)
736char *path1, *path2, *path3;
737{
738 if (creat_symlink(path1, path2) == -1)
739 return(0);
740 else if (creat_object(path3) == -1)
741 return(0);
742 return(1);
743}
744
745/***********************************************************************
746 *
747 * This routine checks if symbolic link file is a symbolic link file.
748 *
749 * Argument one is a pathname of object file
750 * Argument two is symbolic link file name
751 * Argument three is regular file name
752 *
753 ***********************************************************************/
754ck_symlink(path1, path2, path3)
755char *path1, *path2, *path3;
756{
757 int ret;
758
759 if ((ret=see_if_a_symlink(path2)) == -1) {
760 TEST_RESULT=TBROK;
761 sprintf(test_msg,
762 "lstat(2) Failure when accessing %s symbolic link file which should contain %s path to %s file ",
763 path2, path1, path3);
764 return(0);
765 }
766 else if (ret == 0) {
767 TEST_RESULT=TBROK;
768 sprintf(test_msg,
769 "%s is not a symbolic link file which contains %s path to %s file",
770 path2, path1, path3);
771 return(0);
772 }
773 return(1);
774}
775
776/***********************************************************************
777 *
778 * This routine checks if symbolic link file points at object file.
779 *
780 * Argument one is a pathname of object file
781 * Argument two is symbolic link file name
782 * Argument three is regular file name
783 *
784 ***********************************************************************/
785ck_both(path1, path2, path3)
786char *path1, *path2, *path3;
787{
788 if (ck_symlink(path1, path2, path3) == 0)
789 return(0);
790 else if ((stat(path3, &statter) == -1) && (errno == ENOENT)) {
791 TEST_RESULT=TBROK;
792 sprintf(test_msg, "stat(2) Failure when accessing %s object file ", path3);
793 return(0);
794 }
795 else if ((stat(path2, &asymlink) == -1) && (errno == ENOENT)) {
796 TEST_RESULT=TBROK;
797 sprintf(test_msg, "stat(2) Failure when accessing %s symbolic link file ",
798 path2);
799 return(0);
800 }
801 else if (statter.st_ino != asymlink.st_ino) {
802 TEST_RESULT=TBROK;
803 sprintf(test_msg,
804 "stat(2) Failure when accessing %s object file through %s symbolic link file ",
805 path3, path2);
806 return(0);
807 }
808 return(1);
809
810}
811
812/***********************************************************************
813 * This routine populates full_path with a pathname whose length exceeds
814 * the PATH_MAX define value in param.h
815 *
816 * Argument one is a pathname of object file
817 * Argument two is symbolic link file name
818 * Argument three is regular file name
819 ***********************************************************************/
820creat_path_max(path1, path2, path3)
821char *path1, *path2, *path3;
822{
823 int ctr, to_go, size, whole_chunks;
824 char *cwd, *getcwd();
825
826 if ((cwd = getcwd((char *)NULL, 64)) == NULL)
827 {
828 TEST_RESULT=TBROK;
829 sprintf(test_msg,
830 "getcwd(3) Failure in setup of %s %s %s test case object elements",
831 path1, path2, path3);
832 return(0);
833 }
834 cwd = getcwd((char *)NULL, 64);
835 size = strlen(cwd);
836
837 to_go = PATH_MAX - size;
838 size = strlen(path1);
839 whole_chunks = to_go / size;
840 strcpy(full_path, cwd);
841 for (ctr=0; ctr < whole_chunks; ctr++) {
842 strcat(full_path, path1);
843 }
844 size= strlen(full_path);
845 to_go = PATH_MAX - size;
846 strcat(full_path, "/");
847 for (ctr=0; ctr < to_go; ctr++)
848 strcat(full_path, "Z");
849
850 return(1);
851}
852
853/***********************************************************************
854 * This routine checks that full_path's length exceeds the PATH_MAX
855 * define value in param.h
856 *
857 * Argument one is a pathname of object file
858 * Argument two is symbolic link file name
859 * Argument three is regular file name
860 ***********************************************************************/
861ck_path_max(path1, path2, path3)
862char *path1, *path2, *path3;
863{
864 if (strlen(full_path) == (PATH_MAX+1))
865 return(1);
866 else
867 {
868 TEST_RESULT=TBROK;
869 sprintf(test_msg, "%s %d %s %s %s %s",
870 "full_path character array length was not", (PATH_MAX+1),
871 "characters long for test case object elements",
872 path1, path2, path3);
873 return(0);
874 }
875}
876
877/***********************************************************************
878 * This routine checks if the stat(2) and lstat(2) calls return the same
879 * information when the path is not a symbolic link file
880 *
881 * Argument one is a pathname of object file
882 * Argument two is symbolic link file name
883 * Argument three is regular file name
884 *
885 ***********************************************************************/
886ck_object(path1, path2, path3)
887char *path1, *path2, *path3;
888{
889 int ret;
890
891 if ((ret=see_if_a_symlink(path1)) < 0) {
892 TEST_RESULT=TFAIL;
893 sprintf(test_msg,
894 "lstat(2) failed to return inode information for a regular object file");
895 return(0);
896 }
897 else if (ret == 1) {
898 TEST_RESULT=TFAIL;
899 sprintf(test_msg,
900 "lstat(2) detected a regular object file as a symbolic link file");
901 return(0);
902 }
903 else if (stat(path1, &statter) == -1) {
904 TEST_RESULT=TBROK;
905 sprintf(test_msg,
906 "stat(2) failed to return inode information for a regular object file");
907 return(0);
908 }
909 else if (bcmp((char *)&statter, (char *)&asymlink, sizeof(statter)) != 0) {
910 TEST_RESULT=TFAIL;
911 sprintf(test_msg,
912 "lstat(2) and stat(2) do not return same inode information for an object file");
913 return(0);
914
915 }
916 return(1);
917}
918
919/***********************************************************************
920 * Main test case processing function
921 *
922 * Argument is a ptr into the all_tcses array of structures of type tcses
923 ***********************************************************************/
924do_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 */
2014void
2015help()
2016{
2017 int ind;
2018
2019 printf("%s", STD_opts_help());
2020 printf(" -h : print this help message and exit\n");
2021 printf(" -T tcid : determines which tests cases to execute:\n");
2022
2023 for (ind=0; ind<sizeof(all_tcses)/sizeof(struct tcses ); ind++) {
2024 printf(" %s/%s - %s\n", all_tcses[ind].tcid, all_tcses[ind].syscall,
2025 all_tcses[ind].desc);
2026 }
2027}