188 lines
4.4 KiB
C
188 lines
4.4 KiB
C
/*
|
|
* 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"
|
|
|
|
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;
|
|
unsigned int i;
|
|
int lc;
|
|
|
|
tst_parse_opts(ac, av, NULL, NULL);
|
|
|
|
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 < ARRAY_SIZE(fd); i++)
|
|
close(fd[i]);
|
|
for (i = 0; i < 8; i++) {
|
|
sprintf(fname, "./fcntl%u.%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)
|
|
{
|
|
tst_rmdir();
|
|
|
|
}
|