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 221void setup(void); 222void cleanup(void); 223void help(void); 224void delete_files(char *path1, char *path2); 225struct all_test_cases; 226void do_EEXIST(struct all_test_cases *tc_ptr); 227void do_ENOENT(struct all_test_cases *tc_ptr); 228void do_ELOOP(struct all_test_cases *tc_ptr); 229void do_ENOTDIR(struct all_test_cases *tc_ptr); 230void do_EXDEV(struct all_test_cases *tc_ptr); 231void do_ENAMETOOLONG(struct all_test_cases *tc_ptr); 232void do_EINVAL(struct all_test_cases *tc_ptr); 233void do_readlink(struct all_test_cases *tc_ptr); 234void do_stat(struct all_test_cases *tc_ptr); 235void do_chdir(struct all_test_cases *tc_ptr); 236void do_link(struct all_test_cases *tc_ptr); 237void do_unlink(struct all_test_cases *tc_ptr); 238void do_chmod(struct all_test_cases *tc_ptr); 239void do_utime(struct all_test_cases *tc_ptr); 240void do_rename(struct all_test_cases *tc_ptr); 241void do_open(struct all_test_cases *tc_ptr); 242struct tcses; 243int do_syscalltests(struct tcses *tcs); 244struct 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 */ 278const 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 */ 316int creat_both(char *path1, char *path2, char *path3); 317int creat_symlink(char *path1, char *path2, char *_path3); 318int creat_path_max(char *path1, char *path2, char *path3); 319int ck_symlink(char *path1, char *path2, char *path3); 320int creat_object(char *path1, char *_path2, char *_path3); 321int ck_object(char *path1, char *path2, char *path3); 322int ck_both(char *path1, char *path2, char *path3); 323int ck_path_max(char *path1, char *path2, char *path3); 324 325/* 326 * Define test cases 327 */ 328struct 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 */ 448struct 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"}, { 489OPEN, "open", 5, &test_objects[39], 490 "Create/Open a File For Reading Or Writing via symlink"},}; 491 492/* 493 * Define GLOBAL variables 494 */ 495 496int TST_TOTAL; 497int TEST_RESULT; 498time_t a_time_value = 100; 499char *TCID; 500char *Selectedtests = NULL; /* Name (tcid) of selected test cases */ 501char test_msg[BUFMAX]; 502char full_path[PATH_MAX + 1 + 1]; /* Add one for '\0' and another to exceed the PATH_MAX limit, see creat_path_max() */ 503 504struct stat asymlink, statter; 505char Buffer[1024]; 506char Buf[1024]; 507 508char *Tcid = NULL; 509 510option_t Options[] = { 511 {"T:", NULL, &Tcid}, /* -T tcid option */ 512 {NULL, NULL, NULL} 513}; 514 515/*********************************************************************** 516 * MAIN 517 ***********************************************************************/ 518int 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 ***********************************************************************/ 585struct 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 ***********************************************************************/ 622static 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 ***********************************************************************/ 636void 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 ***********************************************************************/ 650int 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 ***********************************************************************/ 678int 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 ***********************************************************************/ 714int 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 ***********************************************************************/ 732int 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 ***********************************************************************/ 761int 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 ***********************************************************************/ 796int 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 ***********************************************************************/ 835int 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 ***********************************************************************/ 859int 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 ***********************************************************************/ 894int 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 ***********************************************************************/ 1024void 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 ***********************************************************************/ 1073void 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 ***********************************************************************/ 1152void 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 ***********************************************************************/ 1239void 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 ***********************************************************************/ 1269void 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 ***********************************************************************/ 1304void 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 ***********************************************************************/ 1352void 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 ***********************************************************************/ 1382void 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 ***********************************************************************/ 1418void 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 ***********************************************************************/ 1477void 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 ***********************************************************************/ 1530void 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 ***********************************************************************/ 1587void 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 ***********************************************************************/ 1625void 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 ***********************************************************************/ 1663void 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 ***********************************************************************/ 1719void 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 ***********************************************************************/ 1756void 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 ***************************************************************/ 1853void 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 ***************************************************************/ 1869void cleanup(void) 1870{ 1871 1872 tst_rmdir(); 1873 1874} 1875 1876void 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