blob: a8cdd50810392c2fcccefb209a4431942ef0cce4 [file] [log] [blame]
/*
* 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();
}