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