| /* |
| * NAME |
| * fcntl01.c |
| * |
| * DESCRIPTION |
| * Test F_DUPFD, F_SETFL cmds of fcntl |
| * |
| * CALLS |
| * fcntl |
| * |
| * ALGORITHM |
| * |
| * 1. Testing F_DUPFD cmd with arg less than, equal to, and greater |
| * than the next available file descriptor. |
| * |
| * 2. Checking F_SETFL cmd with each valid flag (O_NDELAY, O_APPEND). |
| * |
| * 3. Checking, setting and reading `close on exec' flag. |
| * |
| * USAGE |
| * fcntl01 |
| * |
| * HISTORY |
| * 07/2001 Ported by Wayne Boyer |
| * 09/2002 added fd2 array to remove statid fds |
| * |
| * RESTRICTIONS |
| * None |
| * |
| */ |
| |
| #include <fcntl.h> |
| #include <errno.h> |
| #include <sys/types.h> |
| #include <sys/stat.h> |
| #include "test.h" |
| #include "usctest.h" |
| |
| void setup(void); |
| void cleanup(void); |
| |
| char *TCID = "fcntl01"; |
| int TST_TOTAL = 1; |
| |
| int main(int ac, char **av) |
| { |
| int flags; |
| char fname[40]; |
| int fd[10], fd2[10]; |
| int mypid, i; |
| int lc; |
| char *msg; |
| |
| if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) |
| tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); |
| |
| setup(); |
| |
| /* check for looping state if -i option is given */ |
| for (lc = 0; TEST_LOOPING(lc); lc++) { |
| |
| tst_count = 0; |
| |
| mypid = getpid(); |
| for (i = 0; i < 8; i++) { |
| sprintf(fname, "./fcntl%d.%d", i, mypid); |
| if ((fd[i] = |
| open(fname, O_WRONLY | O_CREAT, 0666)) == -1) |
| tst_resm(TBROK | TERRNO, "open failed"); |
| fd2[i] = fd[i]; |
| } |
| |
| close(fd[2]); |
| close(fd[3]); |
| close(fd[4]); |
| close(fd[5]); |
| |
| if ((fd[2] = fcntl(fd[1], F_DUPFD, 1)) == -1) |
| tst_resm(TFAIL | TERRNO, "fcntl(.., 1) failed"); |
| |
| if (fd[2] < fd2[2]) |
| tst_resm(TFAIL, "new fd has unexpected value: " |
| "got %d, expected greater than %d", fd[2], 5); |
| |
| if ((fd[4] = fcntl(fd[1], F_DUPFD, fd2[3])) < 0) |
| tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[3]) failed"); |
| |
| if (fd[4] < fd2[3]) |
| tst_resm(TFAIL, "new fd has unexpected value, got %d, " |
| "expect greater than %d", fd[4], fd2[3]); |
| |
| if ((fd[8] = fcntl(fd[1], F_DUPFD, fd2[5])) < 0) |
| tst_resm(TFAIL | TERRNO, "fcntl(.., fd2[5]) failed"); |
| |
| if (fd[8] != fd2[5]) |
| tst_resm(TFAIL, "new fd has unexpected value: " |
| "got %d, expected %d", fd[8], fd2[5]); |
| /* //block1: */ |
| flags = fcntl(fd[2], F_GETFL, 0); |
| if ((flags & O_WRONLY) == 0) |
| tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x", |
| flags, O_WRONLY); |
| |
| /* Check setting of no_delay flag */ |
| if (fcntl(fd[2], F_SETFL, O_NDELAY) == -1) |
| tst_resm(TBROK | TERRNO, "fcntl(.., O_NDELAY) failed"); |
| |
| flags = fcntl(fd[2], F_GETFL, 0); |
| if ((flags & (O_NDELAY | O_WRONLY)) == 0) |
| tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x", |
| flags, O_NDELAY | O_WRONLY); |
| |
| /* Check of setting append flag */ |
| if (fcntl(fd[2], F_SETFL, O_APPEND) == -1) |
| tst_resm(TFAIL | TERRNO, "fcntl(.., O_APPEND) failed"); |
| |
| flags = fcntl(fd[2], F_GETFL, 0); |
| if ((flags & (O_APPEND | O_WRONLY)) == 0) |
| tst_resm(TFAIL, "unexpected flag ox%x, expected 0x%x", |
| flags, O_APPEND | O_WRONLY); |
| |
| /* Check setting flags together */ |
| if (fcntl(fd[2], F_SETFL, O_NDELAY | O_APPEND) < 0) |
| tst_resm(TFAIL, "fcntl(.., O_NDELAY|O_APPEND) failed"); |
| |
| flags = fcntl(fd[2], F_GETFL, 0); |
| if ((flags & (O_NDELAY | O_APPEND | O_WRONLY)) == 0) |
| tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x", |
| flags, |
| O_NDELAY | O_APPEND | O_SYNC | O_WRONLY); |
| |
| /* Check that flags are not cummulative */ |
| if (fcntl(fd[2], F_SETFL, 0) == -1) |
| tst_resm(TFAIL, "fcntl(.., 0) failed"); |
| |
| flags = fcntl(fd[2], F_GETFL, 0); |
| if ((flags & O_WRONLY) == 0) |
| tst_resm(TFAIL, "unexpected flag 0x%x, expected 0x%x", |
| flags, O_WRONLY); |
| |
| /* //block2: */ |
| /* |
| * Check ability to set (F_SETFD) the close on exec flag |
| */ |
| if ((flags = fcntl(fd[2], F_GETFD, 0)) < 0) |
| tst_resm(TFAIL | TERRNO, |
| "fcntl(.., F_GETFD, ..) #1 failed"); |
| if (flags != 0) |
| tst_resm(TFAIL, "unexpected flags got 0x%x expected " |
| "0x%x", flags, 0); |
| if ((flags = fcntl(fd[2], F_SETFD, 1)) == -1) |
| tst_resm(TFAIL, "fcntl(.., F_SETFD, ..) failed"); |
| if ((flags = fcntl(fd[2], F_GETFD, 0)) == -1) |
| tst_resm(TFAIL | TERRNO, |
| "fcntl(.., F_GETFD, ..) #2 failed"); |
| if (flags != 1) |
| tst_resm(TFAIL, "unexpected flags, got 0x%x, " |
| "expected 0x%x", flags, 1); |
| |
| for (i = 0; i < sizeof(fd) / sizeof(*fd); i++) |
| close(fd[i]); |
| for (i = 0; i < 8; i++) { |
| sprintf(fname, "./fcntl%d.%d", i, mypid); |
| if ((unlink(fname)) == -1) |
| tst_resm(TFAIL | TERRNO, |
| "unlinking %s failed", fname); |
| } |
| } |
| cleanup(); |
| tst_exit(); |
| } |
| |
| /* |
| * setup |
| * performs all ONE TIME setup for this test |
| */ |
| void setup(void) |
| { |
| tst_sig(FORK, DEF_HANDLER, cleanup); |
| umask(0); |
| TEST_PAUSE; |
| tst_tmpdir(); |
| } |
| |
| void cleanup(void) |
| { |
| TEST_CLEANUP; |
| |
| tst_rmdir(); |
| |
| } |