29<->38
20<->39
This commit is contained in:
Ben Gras 2005-09-19 13:44:31 +00:00
parent d0d8010415
commit d969f7b4bc
5 changed files with 1731 additions and 1730 deletions

View file

@ -13,7 +13,8 @@ badones= # list of tests that failed
# Print test welcome message
clr
echo "Running POSIX compliance test suite. There are 42 tests in total."
echo "These tests may take more than 20 minutes, even on fast systems."
echo "The last few tests may take up to 15 minutes each, even on fast"
echo "systems."
echo " "
# Run all the tests, keeping track of who failed.

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,16 @@
/* Many of the tests require 1.6.n, n > 16, so we may as well assume that
* POSIX signals are implemented.
*/
#define SIGACTION
/* test29: dup() dup2() Author: Jan-Mark Wams (jms@cs.vu.nl) */
/* test29: read(), write() Author: Jan-Mark Wams (jms@cs.vu.nl) */
/* The definition of ``dup2()'' is realy a big mess! For:
**
** (1) if fildes2 is less than zero or greater than {OPEN_MAX}
** errno has to set to [EBADF]. But if fildes2 equals {OPEN_MAX}
** errno has to be set to [EINVAL]. And ``fcntl(F_DUPFD...)'' always
** returns [EINVAL] if fildes2 is out of range!
**
** (2) if the number of file descriptors would exceed {OPEN_MAX}, or no
** file descriptors above fildes2 are available, errno has to be set
** to [EMFILE]. But this can never occur!
*/
#include <sys/types.h>
#include <sys/stat.h>
@ -15,27 +22,30 @@
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 3
#define BUF_SIZE 1024
#define ITERATIONS 10
#define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
#define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
#define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
#define IS_CLOEXEC(fd) ((fcntl(fd, F_GETFD) & FD_CLOEXEC) == FD_CLOEXEC)
#define SET_CLOEXEC(fd) fcntl(fd, F_SETFD, FD_CLOEXEC)
int errct = 0;
int subtest = 1;
int superuser;
int signumber = 0;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test29a, (void));
_PROTOTYPE(void test29b, (void));
_PROTOTYPE(void test29c, (void));
_PROTOTYPE(void setsignumber, (int _signumber));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
@ -52,7 +62,6 @@ char *argv[];
System("rm -rf DIR_29; mkdir DIR_29");
Chdir("DIR_29");
superuser = (geteuid() == 0);
umask(0000);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test29a();
@ -63,655 +72,146 @@ char *argv[];
}
void test29a()
{ /* Try normal operation. */
int fd1;
struct stat st1, st2;
time_t time1;
char buf[BUF_SIZE];
int stat_loc;
int i, j;
int tube[2];
{
int fd1, fd2, fd3, fd4, fd5;
struct flock flock;
subtest = 1;
/* Basic checking. */
if ((fd1 = dup(0)) != 3) e(1);
if ((fd2 = dup(0)) != 4) e(2);
if ((fd3 = dup(0)) != 5) e(3);
if ((fd4 = dup(0)) != 6) e(4);
if ((fd5 = dup(0)) != 7) e(5);
if (close(fd2) != 0) e(6);
if (close(fd4) != 0) e(7);
if ((fd2 = dup(0)) != 4) e(8);
if ((fd4 = dup(0)) != 6) e(9);
if (close(fd1) != 0) e(10);
if (close(fd3) != 0) e(11);
if (close(fd5) != 0) e(12);
if ((fd1 = dup(0)) != 3) e(13);
if ((fd3 = dup(0)) != 5) e(14);
if ((fd5 = dup(0)) != 7) e(15);
if (close(fd1) != 0) e(16);
if (close(fd2) != 0) e(17);
if (close(fd3) != 0) e(18);
if (close(fd4) != 0) e(19);
if (close(fd5) != 0) e(20);
/* FD_CLOEXEC should be cleared. */
if ((fd1 = dup(0)) != 3) e(21);
if (SET_CLOEXEC(fd1) == -1) e(22);
if (!IS_CLOEXEC(fd1)) e(23);
if ((fd2 = dup(fd1)) != 4) e(24);
if ((fd3 = dup(fd2)) != 5) e(25);
if (IS_CLOEXEC(fd2)) e(26);
if (IS_CLOEXEC(fd3)) e(27);
if (SET_CLOEXEC(fd2) == -1) e(28);
if (!IS_CLOEXEC(fd2)) e(29);
if (IS_CLOEXEC(fd3)) e(30);
if (close(fd1) != 0) e(31);
if (close(fd2) != 0) e(32);
if (close(fd3) != 0) e(33);
/* Locks should be shared, so we can lock again. */
System("echo 'Hallo' > file");
if ((fd1 = open("file", O_RDWR)) != 3) e(34);
flock.l_whence = SEEK_SET;
flock.l_start = 0;
flock.l_len = 10;
flock.l_type = F_WRLCK;
if (fcntl(fd1, F_SETLK, &flock) == -1) e(35);
if (fcntl(fd1, F_SETLK, &flock) == -1) e(36);
if ((fd2 = dup(fd1)) != 4) e(37);
if (fcntl(fd1, F_SETLK, &flock) == -1) e(38);
if (fcntl(fd1, F_GETLK, &flock) == -1) e(39);
#if 0 /* XXX - see test7.c */
if (flock.l_type != F_WRLCK) e(40);
if (flock.l_pid != getpid()) e(41);
#endif /* 0 */
flock.l_type = F_WRLCK;
if (fcntl(fd2, F_GETLK, &flock) == -1) e(42);
#if 0 /* XXX - see test7.c */
if (flock.l_type != F_WRLCK) e(43);
if (flock.l_pid != getpid()) e(44);
#endif /* 0 */
if (close(fd1) != 0) e(45);
if (close(fd2) != 0) e(46);
System("rm -rf ../DIR_29/*");
/* Let's open bar. */
if ((fd1 = open("bar", O_RDWR | O_CREAT, 0777)) != 3) e(1);
Stat("bar", &st1);
/* Writing nothing should not affect the file at all. */
if (write(fd1, "", 0) != 0) e(2);
Stat("bar", &st2);
if (st1.st_uid != st2.st_uid) e(3);
if (st1.st_gid != st2.st_gid) e(4); /* should be same */
if (st1.st_mode != st2.st_mode) e(5);
if (st1.st_size != st2.st_size) e(6);
if (st1.st_nlink != st2.st_nlink) e(7);
if (st1.st_mtime != st2.st_mtime) e(8);
if (st1.st_ctime != st2.st_ctime) e(9);
if (st1.st_atime != st2.st_atime) e(10);
/* A write should update some status fields. */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (write(fd1, "foo", 4) != 4) e(11);
Stat("bar", &st2);
if (st1.st_mode != st2.st_mode) e(12);
if (st1.st_size >= st2.st_size) e(13);
if ((off_t) 4 != st2.st_size) e(14);
if (st1.st_nlink != st2.st_nlink) e(15);
if (st1.st_mtime >= st2.st_mtime) e(16);
if (st1.st_ctime >= st2.st_ctime) e(17);
if (st1.st_atime != st2.st_atime) e(18);
/* Lseeks should not change the file status. */
if (lseek(fd1, (off_t) - 2, SEEK_END) != 2) e(19);
Stat("bar", &st1);
if (st1.st_mode != st2.st_mode) e(20);
if (st1.st_size != st2.st_size) e(21);
if (st1.st_nlink != st2.st_nlink) e(22);
if (st1.st_mtime != st2.st_mtime) e(23);
if (st1.st_ctime != st2.st_ctime) e(24);
if (st1.st_atime != st2.st_atime) e(25);
/* Writing should start at the current (2) position. */
if (write(fd1, "foo", 4) != 4) e(26);
Stat("bar", &st2);
if (st1.st_mode != st2.st_mode) e(27);
if (st1.st_size >= st2.st_size) e(28);
if ((off_t) 6 != st2.st_size) e(29);
if (st1.st_nlink != st2.st_nlink) e(30);
if (st1.st_mtime > st2.st_mtime) e(31);
if (st1.st_ctime > st2.st_ctime) e(32);
if (st1.st_atime != st2.st_atime) e(33);
/* A read of zero bytes should not affect anything. */
if (read(fd1, buf, 0) != 0) e(34);
Stat("bar", &st1);
if (st1.st_uid != st2.st_uid) e(35);
if (st1.st_gid != st2.st_gid) e(36); /* should be same */
if (st1.st_mode != st2.st_mode) e(37);
if (st1.st_size != st2.st_size) e(38);
if (st1.st_nlink != st2.st_nlink) e(39);
if (st1.st_mtime != st2.st_mtime) e(40);
if (st1.st_ctime != st2.st_ctime) e(41);
if (st1.st_atime != st2.st_atime) e(42);
/* The file now should contain ``fofoo\0'' Let's check that. */
if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(43);
if (read(fd1, buf, BUF_SIZE) != 6) e(44);
if (strcmp(buf, "fofoo") != 0) e(45);
/* Only the Access Time should be updated. */
Stat("bar", &st2);
if (st1.st_mtime != st2.st_mtime) e(46);
if (st1.st_ctime != st2.st_ctime) e(47);
if (st1.st_atime >= st2.st_atime) e(48);
/* A read of zero bytes should do nothing even at the end of the file. */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (read(fd1, buf, 0) != 0) e(49);
Stat("bar", &st1);
if (st1.st_size != st2.st_size) e(50);
if (st1.st_mtime != st2.st_mtime) e(51);
if (st1.st_ctime != st2.st_ctime) e(52);
if (st1.st_atime != st2.st_atime) e(53);
/* Reading should be done from the current offset. */
if (read(fd1, buf, BUF_SIZE) != 0) e(54);
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(55);
if (read(fd1, buf, BUF_SIZE) != 4) e(56);
if (strcmp(buf, "foo") != 0) e(57);
/* Reading should effect the current file position. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(58);
if (read(fd1, buf, 1) != 1) e(59);
if (*buf != 'f') e(60);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 3) e(61);
if (read(fd1, buf, 1) != 1) e(62);
if (*buf != 'o') e(63);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(64);
if (read(fd1, buf, 1) != 1) e(65);
if (*buf != 'o') e(66);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 5) e(67);
if (read(fd1, buf, 1) != 1) e(68);
if (*buf != '\0') e(69);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(70);
/* Read's at EOF should return 0. */
if (read(fd1, buf, BUF_SIZE) != 0) e(71);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(72);
if (read(fd1, buf, BUF_SIZE) != 0) e(73);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(74);
if (read(fd1, buf, BUF_SIZE) != 0) e(75);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(76);
if (read(fd1, buf, BUF_SIZE) != 0) e(77);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(78);
if (read(fd1, buf, BUF_SIZE) != 0) e(79);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(80);
/* Writing should not always change the file size. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(81);
if (write(fd1, "ba", 2) != 2) e(82);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(83);
Stat("bar", &st1);
if (st1.st_size != 6) e(84);
/* Kill the \0 at the end. */
if (lseek(fd1, (off_t) 5, SEEK_SET) != 5) e(85);
if (write(fd1, "x", 1) != 1) e(86);
/* And close the bar. */
if (close(fd1) != 0) e(87);
/* Try some stuff with O_APPEND. Bar contains ``fobaox'' */
if ((fd1 = open("bar", O_RDWR | O_APPEND)) != 3) e(88);
/* No matter what the file position is. Writes should append. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(89);
if (write(fd1, "y", 1) != 1) e(90);
Stat("bar", &st1);
if (st1.st_size != (off_t) 7) e(91);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 7) e(92);
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(93);
if (write(fd1, "z", 2) != 2) e(94);
/* The file should contain ``fobaoxyz\0'' == 9 chars long. */
Stat("bar", &st1);
if (st1.st_size != (off_t) 9) e(95);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(96);
/* Reading on a O_APPEND flag should be from the current offset. */
if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(97);
if (read(fd1, buf, BUF_SIZE) != 9) e(98);
if (strcmp(buf, "fobaoxyz") != 0) e(99);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(100);
if (close(fd1) != 0) e(101);
/* Let's test fifo writes. First blocking. */
if (mkfifo("fifo", 0777) != 0) e(102);
/* Read from fifo but no writer. */
System("rm -rf /tmp/sema.29a");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(103);
system("> /tmp/sema.29a");
system("while test -f /tmp/sema.29a; do sleep 1; done");
errno =0;
if (read(fd1, buf, BUF_SIZE) != 0) e(104);
if (read(fd1, buf, BUF_SIZE) != 0) e(105);
if (read(fd1, buf, BUF_SIZE) != 0) e(106);
if (close(fd1) != 0) e(107);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(108);
while (stat("/tmp/sema.29a", &st1) != 0) sleep(1);
if (close(fd1) != 0) e(109);
unlink("/tmp/sema.29a");
if (wait(&stat_loc) == -1) e(110);
if (stat_loc != 0) e(111); /* Alarm? */
}
/* Read from fifo should wait for writer. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(112);
if (read(fd1, buf, BUF_SIZE) != 10) e(113);
if (strcmp(buf, "Hi reader") != 0) e(114);
if (close(fd1) != 0) e(115);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(116);
sleep(1);
if (write(fd1, "Hi reader", 10) != 10) e(117);
if (close(fd1) != 0) e(118);
if (wait(&stat_loc) == -1) e(119);
if (stat_loc != 0) e(120); /* Alarm? */
}
/* Read from fifo should wait for all writers to close. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(121);
if (close(fd1) != 0) e(122);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(123);
sleep(1);
if (close(fd1) != 0) e(124);
if (wait(&stat_loc) == -1) e(125);
if (stat_loc != 0) e(126); /* Alarm? */
}
exit(stat_loc);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(127);
if (read(fd1, buf, BUF_SIZE) != 0) e(128);
if (close(fd1) != 0) e(129);
if (wait(&stat_loc) == -1) e(130);
if (stat_loc != 0) e(131); /* Alarm? */
}
/* PIPE_BUF has to have a nice value. */
if (PIPE_BUF < 5) e(132);
if (BUF_SIZE < 1000) e(133);
/* Writes of blocks smaller than PIPE_BUF should be atomic. */
System("rm -rf /tmp/sema.29b;> /tmp/sema.29b");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(134);
for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
system("while test -f /tmp/sema.29b; do sleep 1; done");
if (close(fd1) != 0) e(135);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(136);
for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
while (stat("/tmp/sema.29b", &st1) == 0) sleep(1);
if (close(fd1) != 0) e(137);
if (wait(&stat_loc) == -1) e(138);
if (stat_loc != 0) e(139); /* Alarm? */
}
exit(stat_loc);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(140);
i = 0;
memset(buf, '\0', BUF_SIZE);
/* Read buffer full or till EOF. */
do {
j = read(fd1, buf + i, BUF_SIZE - i);
if (j > 0) {
if (j % 5 != 0) e(141);
i += j;
}
} while (j > 0 && i < 1000);
/* Signal the children to close write ends. This should not be */
/* Necessary. But due to a bug in 1.16.6 this is necessary. */
unlink("/tmp/sema.29b");
if (j < 0) e(142);
if (i != 1000) e(143);
if (wait(&stat_loc) == -1) e(144);
if (stat_loc != 0) e(145); /* Alarm? */
/* Check 200 times 1234. */
for (i = 0; i < 200; i++)
if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
if (i != 200) e(146);
if (buf[1000] != '\0') e(147);
if (buf[1005] != '\0') e(148);
if (buf[1010] != '\0') e(149);
if (read(fd1, buf, BUF_SIZE) != 0) e(150);
if (close(fd1) != 0) e(151);
}
/* Read from pipe should wait for writer. */
if (pipe(tube) != 0) e(152);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[1]) != 0) e(153);
if (read(tube[0], buf, BUF_SIZE) != 10) e(154);
if (strcmp(buf, "Hi reader") != 0) e(155);
if (close(tube[0]) != 0) e(156);
exit(0);
default:
if (close(tube[0]) != 0) e(157);
sleep(1);
if (write(tube[1], "Hi reader", 10) != 10) e(158);
if (close(tube[1]) != 0) e(159);
if (wait(&stat_loc) == -1) e(160);
if (stat_loc != 0) e(161); /* Alarm? */
}
/* Read from pipe should wait for all writers to close. */
if (pipe(tube) != 0) e(162);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[0]) != 0) e(163);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[1]) != 0) e(164);
exit(0);
default:
sleep(1);
if (close(tube[1]) != 0) e(165);
if (wait(&stat_loc) == -1) e(166);
if (stat_loc != 0) e(167); /* Alarm? */
}
exit(stat_loc);
default:
if (close(tube[1]) != 0) e(168);
if (read(tube[0], buf, BUF_SIZE) != 0) e(169);
if (close(tube[0]) != 0) e(170);
if (wait(&stat_loc) == -1) e(171);
if (stat_loc != 0) e(172); /* Alarm? */
}
/* Writes of blocks smaller than PIPE_BUF should be atomic. */
System("rm -rf /tmp/sema.29c;> /tmp/sema.29c");
if (pipe(tube) != 0) e(173);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[0]) != 0) e(174);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
system("while test -f /tmp/sema.29c; do sleep 1; done");
if (close(tube[1]) != 0) e(175);
exit(0);
default:
for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
while (stat("/tmp/sema.29c", &st1) == 0) sleep(1);
if (close(tube[1]) != 0) e(176);
if (wait(&stat_loc) == -1) e(177);
if (stat_loc != 0) e(178); /* Alarm? */
}
exit(stat_loc);
default:
i = 0;
if (close(tube[1]) != 0) e(179);
memset(buf, '\0', BUF_SIZE);
do {
j = read(tube[0], buf + i, BUF_SIZE - i);
if (j > 0) {
if (j % 5 != 0) e(180);
i += j;
} else
break; /* EOF seen. */
} while (i < 1000);
unlink("/tmp/sema.29c");
if (j < 0) e(181);
if (i != 1000) e(182);
if (close(tube[0]) != 0) e(183);
if (wait(&stat_loc) == -1) e(184);
if (stat_loc != 0) e(185); /* Alarm? */
/* Check 200 times 1234. */
for (i = 0; i < 200; i++)
if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
if (i != 200) e(186);
}
}
void test29b()
{
int i, fd, stat_loc;
char buf[BUF_SIZE];
char buf2[BUF_SIZE];
struct stat st;
int fd;
char buf[32];
subtest = 2;
/* Test file called ``file''. */
System("echo 'Hallo!' > file");
/* Check dup2() call with the same fds. Should have no effect. */
if ((fd = open("file", O_RDONLY)) != 3) e(1);
if (read(fd, buf, 2) != 2) e(2);
if (strncmp(buf, "Ha", 2) != 0) e(3);
if (dup2(fd, fd) != fd) e(4);
if (read(fd, buf, 2) != 2) e(5);
if (strncmp(buf, "ll", 2) != 0) e(6);
if (dup2(fd, fd) != fd) e(7);
if (read(fd, buf, 2) != 2) e(8);
if (strncmp(buf, "o!", 2) != 0) e(9);
if (close(fd) != 0) e(10);
/* If dup2() call fails, the fildes2 argument has to stay open. */
if ((fd = open("file", O_RDONLY)) != 3) e(11);
if (read(fd, buf, 2) != 2) e(12);
if (strncmp(buf, "Ha", 2) != 0) e(13);
if (dup2(OPEN_MAX + 3, fd) != -1) e(14);
if (errno != EBADF) e(15);
if (read(fd, buf, 2) != 2) e(16);
if (strncmp(buf, "ll", 2) != 0) e(17);
if (dup2(-4, fd) != -1) e(18);
if (errno != EBADF) e(19);
if (read(fd, buf, 2) != 2) e(20);
if (strncmp(buf, "o!", 2) != 0) e(21);
if (close(fd) != 0) e(22);
System("rm -rf ../DIR_29/*");
/* Lets try sequential writes. */
system("rm -rf /tmp/sema.29d");
System("> testing");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(1);
if (write(fd, "one ", 4) != 4) e(2);
if (close(fd) != 0) e(3);
system("> /tmp/sema.29d");
system("while test -f /tmp/sema.29d; do sleep 1; done");
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(4);
if (write(fd, "three ", 6) != 6) e(5);
if (close(fd) != 0) e(6);
system("> /tmp/sema.29d");
exit(0);
default:
while (stat("/tmp/sema.29d", &st) != 0) sleep(1);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(7);
if (write(fd, "two ", 4) != 4) e(8);
if (close(fd) != 0) e(9);
unlink("/tmp/sema.29d");
while (stat("/tmp/sema.29d", &st) != 0) sleep(1);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(10);
if (write(fd, "four", 5) != 5) e(11);
if (close(fd) != 0) e(12);
if (wait(&stat_loc) == -1) e(13);
if (stat_loc != 0) e(14); /* The alarm went off? */
unlink("/tmp/sema.29d");
}
if ((fd = open("testing", O_RDONLY)) != 3) e(15);
if (read(fd, buf, BUF_SIZE) != 19) e(16);
if (strcmp(buf, "one two three four") != 0) e(17);
if (close(fd) != 0) e(18);
/* Non written bytes in regular files should be zero. */
memset(buf2, '\0', BUF_SIZE);
if ((fd = open("bigfile", O_RDWR | O_CREAT, 0644)) != 3) e(19);
if (lseek(fd, (off_t) 102400, SEEK_SET) != (off_t) 102400L) e(20);
if (read(fd, buf, BUF_SIZE) != 0) e(21);
if (write(fd, ".", 1) != 1) e(22);
Stat("bigfile", &st);
if (st.st_size != (off_t) 102401) e(23);
if (lseek(fd, (off_t) 0, SEEK_SET) != 0) e(24);
for (i = 0; i < 102400 / BUF_SIZE; i++) {
if (read(fd, buf, BUF_SIZE) != BUF_SIZE) e(25);
if (memcmp(buf, buf2, BUF_SIZE) != 0) e(26);
}
if (close(fd) != 0) e(27);
}
void test29c()
{ /* Test correct error behavior. */
char buf[BUF_SIZE];
int fd, tube[2], stat_loc;
struct stat st;
pid_t pid;
#ifdef SIGACTION
struct sigaction act, oact;
#else
#if _ANSI
void (*oldfunc) (int);
#else
void (*oldfunc) ();
#endif
#endif
{
int i;
subtest = 3;
/* Check bad arguments to dup() and dup2(). */
for (i = -OPEN_MAX; i < OPEN_MAX * 2; i++) {
/* ``i'' is a valid and open fd. */
if (i >= 0 && i < 3) continue;
/* If ``i'' is a valid fd it is not open. */
if (dup(i) != -1) e(1);
if (errno != EBADF) e(2);
/* ``i'' Is OPEN_MAX. */
if (i == OPEN_MAX) {
if (dup2(0, i) != -1) e(3);
if (errno != EINVAL) e(4);
}
/* ``i'' Is out of range. */
if (i < 0 || i > OPEN_MAX) {
if (dup2(0, i) != -1) e(5);
if (errno != EBADF) e(6);
}
}
System("rm -rf ../DIR_29/*");
/* To test if writing processes on closed pipes are signumbered. */
#ifdef SIGACTION
act.sa_handler = setsignumber;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGPIPE, &act, &oact) != 0) e(1);
#else
oldfunc = signal(SIGPIPE, setsignumber);
#endif
/* Non valid file descriptors should be an error. */
for (fd = -111; fd < 0; fd++) {
errno = 0;
if (read(fd, buf, BUF_SIZE) != -1) e(2);
if (errno != EBADF) e(3);
}
for (fd = 3; fd < 111; fd++) {
errno = 0;
if (read(fd, buf, BUF_SIZE) != -1) e(4);
if (errno != EBADF) e(5);
}
for (fd = -111; fd < 0; fd++) {
errno = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(6);
if (errno != EBADF) e(7);
}
for (fd = 3; fd < 111; fd++) {
errno = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(8);
if (errno != EBADF) e(9);
}
/* Writing a pipe with no readers should trigger SIGPIPE. */
if (pipe(tube) != 0) e(10);
close(tube[0]);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
signumber = 0;
if (write(tube[1], buf, BUF_SIZE) != -1) e(11);
if (errno != EPIPE) e(12);
if (signumber != SIGPIPE) e(13);
if (close(tube[1]) != 0) e(14);
exit(0);
default:
close(tube[1]);
if (wait(&stat_loc) == -1) e(15);
if (stat_loc != 0) e(16); /* Alarm? */
}
/* Writing a fifo with no readers should trigger SIGPIPE. */
System("> /tmp/sema.29e");
if (mkfifo("fifo", 0666) != 0) e(17);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd = open("fifo", O_WRONLY)) != 3) e(18);
system("while test -f /tmp/sema.29e; do sleep 1; done");
signumber = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(19);
if (errno != EPIPE) e(20);
if (signumber != SIGPIPE) e(21);
if (close(fd) != 0) e(22);
exit(0);
default:
if ((fd = open("fifo", O_RDONLY)) != 3) e(23);
if (close(fd) != 0) e(24);
unlink("/tmp/sema.29e");
if (wait(&stat_loc) == -1) e(25);
if (stat_loc != 0) e(26); /* Alarm? */
}
#ifdef SIGACTION
/* Restore normal (re)action to SIGPIPE. */
if (sigaction(SIGPIPE, &oact, NULL) != 0) e(27);
#else
signal(SIGPIPE, oldfunc);
#endif
/* Read from fifo should return -1 and set errno to EAGAIN. */
System("rm -rf /tmp/sema.29[fgh]");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
system("while test ! -f /tmp/sema.29f; do sleep 1; done");
System("rm -rf /tmp/sema.29f");
if ((fd = open("fifo", O_WRONLY | O_NONBLOCK)) != 3) e(28);
close(creat("/tmp/sema.29g", 0666));
system("while test ! -f /tmp/sema.29h; do sleep 1; done");
if (close(fd) != 0) e(29);
System("rm -rf /tmp/sema.29h");
exit(0);
default:
if ((fd = open("fifo", O_RDONLY | O_NONBLOCK)) != 3) e(30);
close(creat("/tmp/sema.29f", 0666));
system("while test ! -f /tmp/sema.29g; do sleep 1; done");
System("rm -rf /tmp/sema.29g");
if (read(fd, buf, BUF_SIZE) != -1) e(31);
if (errno != EAGAIN) e(32);
if (read(fd, buf, BUF_SIZE) != -1) e(33);
if (errno != EAGAIN) e(34);
if (read(fd, buf, BUF_SIZE) != -1) e(35);
if (errno != EAGAIN) e(36);
close(creat("/tmp/sema.29h", 0666));
while (stat("/tmp/sema.29h", &st) == 0) sleep(1);
if (read(fd, buf, BUF_SIZE) != 0) e(37);
if (close(fd) != 0) e(38);
if (wait(&stat_loc) == -1) e(39);
if (stat_loc != 0) e(40); /* Alarm? */
}
System("rm -rf fifo");
/* If a read is interrupted by a SIGNAL. */
if (pipe(tube) != 0) e(41);
switch (pid = fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
#ifdef SIGACTION
act.sa_handler = setsignumber;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGUSR1, &act, &oact) != 0) e(42);
#else
oldfunc = signal(SIGUSR1, setsignumber);
#endif
if (read(tube[0], buf, BUF_SIZE) != -1) e(43);
if (errno != EINTR) e(44);
if (signumber != SIGUSR1) e(45);
#ifdef SIGACTION
/* Restore normal (re)action to SIGPIPE. */
if (sigaction(SIGUSR1, &oact, NULL) != 0) e(46);
#else
signal(SIGUSR1, oldfunc);
#endif
close(tube[0]);
close(tube[1]);
exit(0);
default:
/* The sleep 1 should give the child time to start the read. */
sleep(1);
close(tube[0]);
kill(pid, SIGUSR1);
wait(&stat_loc);
if (stat_loc != 0) e(47); /* Alarm? */
close(tube[1]);
}
}
void setsignumber(signum)
int signum;
{
signumber = signum;
}
void e(n)

View file

@ -1,16 +1,9 @@
/* test38: dup() dup2() Author: Jan-Mark Wams (jms@cs.vu.nl) */
/* Many of the tests require 1.6.n, n > 16, so we may as well assume that
* POSIX signals are implemented.
*/
#define SIGACTION
/* The definition of ``dup2()'' is realy a big mess! For:
**
** (1) if fildes2 is less than zero or greater than {OPEN_MAX}
** errno has to set to [EBADF]. But if fildes2 equals {OPEN_MAX}
** errno has to be set to [EINVAL]. And ``fcntl(F_DUPFD...)'' always
** returns [EINVAL] if fildes2 is out of range!
**
** (2) if the number of file descriptors would exceed {OPEN_MAX}, or no
** file descriptors above fildes2 are available, errno has to be set
** to [EMFILE]. But this can never occur!
*/
/* test38: read(), write() Author: Jan-Mark Wams (jms@cs.vu.nl) */
#include <sys/types.h>
#include <sys/stat.h>
@ -22,30 +15,27 @@
#include <limits.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <stdio.h>
#define MAX_ERROR 4
#define ITERATIONS 10
#define ITERATIONS 3
#define BUF_SIZE 1024
#define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
#define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
#define Stat(a,b) if (stat(a,b) != 0) printf("Can't stat %s\n", a)
#define IS_CLOEXEC(fd) ((fcntl(fd, F_GETFD) & FD_CLOEXEC) == FD_CLOEXEC)
#define SET_CLOEXEC(fd) fcntl(fd, F_SETFD, FD_CLOEXEC)
int errct = 0;
int subtest = 1;
int superuser;
char MaxName[NAME_MAX + 1]; /* Name of maximum length */
char MaxPath[PATH_MAX]; /* Same for path */
char ToLongName[NAME_MAX + 2]; /* Name of maximum +1 length */
char ToLongPath[PATH_MAX + 1]; /* Same for path, both too long */
int signumber = 0;
_PROTOTYPE(void main, (int argc, char *argv[]));
_PROTOTYPE(void test38a, (void));
_PROTOTYPE(void test38b, (void));
_PROTOTYPE(void test38c, (void));
_PROTOTYPE(void setsignumber, (int _signumber));
_PROTOTYPE(void e, (int number));
_PROTOTYPE(void quit, (void));
@ -62,6 +52,7 @@ char *argv[];
System("rm -rf DIR_38; mkdir DIR_38");
Chdir("DIR_38");
superuser = (geteuid() == 0);
umask(0000);
for (i = 0; i < ITERATIONS; i++) {
if (m & 0001) test38a();
@ -72,146 +63,655 @@ char *argv[];
}
void test38a()
{
int fd1, fd2, fd3, fd4, fd5;
struct flock flock;
{ /* Try normal operation. */
int fd1;
struct stat st1, st2;
time_t time1;
char buf[BUF_SIZE];
int stat_loc;
int i, j;
int tube[2];
subtest = 1;
/* Basic checking. */
if ((fd1 = dup(0)) != 3) e(1);
if ((fd2 = dup(0)) != 4) e(2);
if ((fd3 = dup(0)) != 5) e(3);
if ((fd4 = dup(0)) != 6) e(4);
if ((fd5 = dup(0)) != 7) e(5);
if (close(fd2) != 0) e(6);
if (close(fd4) != 0) e(7);
if ((fd2 = dup(0)) != 4) e(8);
if ((fd4 = dup(0)) != 6) e(9);
if (close(fd1) != 0) e(10);
if (close(fd3) != 0) e(11);
if (close(fd5) != 0) e(12);
if ((fd1 = dup(0)) != 3) e(13);
if ((fd3 = dup(0)) != 5) e(14);
if ((fd5 = dup(0)) != 7) e(15);
if (close(fd1) != 0) e(16);
if (close(fd2) != 0) e(17);
if (close(fd3) != 0) e(18);
if (close(fd4) != 0) e(19);
if (close(fd5) != 0) e(20);
/* FD_CLOEXEC should be cleared. */
if ((fd1 = dup(0)) != 3) e(21);
if (SET_CLOEXEC(fd1) == -1) e(22);
if (!IS_CLOEXEC(fd1)) e(23);
if ((fd2 = dup(fd1)) != 4) e(24);
if ((fd3 = dup(fd2)) != 5) e(25);
if (IS_CLOEXEC(fd2)) e(26);
if (IS_CLOEXEC(fd3)) e(27);
if (SET_CLOEXEC(fd2) == -1) e(28);
if (!IS_CLOEXEC(fd2)) e(29);
if (IS_CLOEXEC(fd3)) e(30);
if (close(fd1) != 0) e(31);
if (close(fd2) != 0) e(32);
if (close(fd3) != 0) e(33);
/* Locks should be shared, so we can lock again. */
System("echo 'Hallo' > file");
if ((fd1 = open("file", O_RDWR)) != 3) e(34);
flock.l_whence = SEEK_SET;
flock.l_start = 0;
flock.l_len = 10;
flock.l_type = F_WRLCK;
if (fcntl(fd1, F_SETLK, &flock) == -1) e(35);
if (fcntl(fd1, F_SETLK, &flock) == -1) e(36);
if ((fd2 = dup(fd1)) != 4) e(37);
if (fcntl(fd1, F_SETLK, &flock) == -1) e(38);
if (fcntl(fd1, F_GETLK, &flock) == -1) e(39);
#if 0 /* XXX - see test7.c */
if (flock.l_type != F_WRLCK) e(40);
if (flock.l_pid != getpid()) e(41);
#endif /* 0 */
flock.l_type = F_WRLCK;
if (fcntl(fd2, F_GETLK, &flock) == -1) e(42);
#if 0 /* XXX - see test7.c */
if (flock.l_type != F_WRLCK) e(43);
if (flock.l_pid != getpid()) e(44);
#endif /* 0 */
if (close(fd1) != 0) e(45);
if (close(fd2) != 0) e(46);
System("rm -rf ../DIR_38/*");
/* Let's open bar. */
if ((fd1 = open("bar", O_RDWR | O_CREAT, 0777)) != 3) e(1);
Stat("bar", &st1);
/* Writing nothing should not affect the file at all. */
if (write(fd1, "", 0) != 0) e(2);
Stat("bar", &st2);
if (st1.st_uid != st2.st_uid) e(3);
if (st1.st_gid != st2.st_gid) e(4); /* should be same */
if (st1.st_mode != st2.st_mode) e(5);
if (st1.st_size != st2.st_size) e(6);
if (st1.st_nlink != st2.st_nlink) e(7);
if (st1.st_mtime != st2.st_mtime) e(8);
if (st1.st_ctime != st2.st_ctime) e(9);
if (st1.st_atime != st2.st_atime) e(10);
/* A write should update some status fields. */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (write(fd1, "foo", 4) != 4) e(11);
Stat("bar", &st2);
if (st1.st_mode != st2.st_mode) e(12);
if (st1.st_size >= st2.st_size) e(13);
if ((off_t) 4 != st2.st_size) e(14);
if (st1.st_nlink != st2.st_nlink) e(15);
if (st1.st_mtime >= st2.st_mtime) e(16);
if (st1.st_ctime >= st2.st_ctime) e(17);
if (st1.st_atime != st2.st_atime) e(18);
/* Lseeks should not change the file status. */
if (lseek(fd1, (off_t) - 2, SEEK_END) != 2) e(19);
Stat("bar", &st1);
if (st1.st_mode != st2.st_mode) e(20);
if (st1.st_size != st2.st_size) e(21);
if (st1.st_nlink != st2.st_nlink) e(22);
if (st1.st_mtime != st2.st_mtime) e(23);
if (st1.st_ctime != st2.st_ctime) e(24);
if (st1.st_atime != st2.st_atime) e(25);
/* Writing should start at the current (2) position. */
if (write(fd1, "foo", 4) != 4) e(26);
Stat("bar", &st2);
if (st1.st_mode != st2.st_mode) e(27);
if (st1.st_size >= st2.st_size) e(28);
if ((off_t) 6 != st2.st_size) e(29);
if (st1.st_nlink != st2.st_nlink) e(30);
if (st1.st_mtime > st2.st_mtime) e(31);
if (st1.st_ctime > st2.st_ctime) e(32);
if (st1.st_atime != st2.st_atime) e(33);
/* A read of zero bytes should not affect anything. */
if (read(fd1, buf, 0) != 0) e(34);
Stat("bar", &st1);
if (st1.st_uid != st2.st_uid) e(35);
if (st1.st_gid != st2.st_gid) e(36); /* should be same */
if (st1.st_mode != st2.st_mode) e(37);
if (st1.st_size != st2.st_size) e(38);
if (st1.st_nlink != st2.st_nlink) e(39);
if (st1.st_mtime != st2.st_mtime) e(40);
if (st1.st_ctime != st2.st_ctime) e(41);
if (st1.st_atime != st2.st_atime) e(42);
/* The file now should contain ``fofoo\0'' Let's check that. */
if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(43);
if (read(fd1, buf, BUF_SIZE) != 6) e(44);
if (strcmp(buf, "fofoo") != 0) e(45);
/* Only the Access Time should be updated. */
Stat("bar", &st2);
if (st1.st_mtime != st2.st_mtime) e(46);
if (st1.st_ctime != st2.st_ctime) e(47);
if (st1.st_atime >= st2.st_atime) e(48);
/* A read of zero bytes should do nothing even at the end of the file. */
time(&time1);
while (time1 >= time((time_t *)0))
;
if (read(fd1, buf, 0) != 0) e(49);
Stat("bar", &st1);
if (st1.st_size != st2.st_size) e(50);
if (st1.st_mtime != st2.st_mtime) e(51);
if (st1.st_ctime != st2.st_ctime) e(52);
if (st1.st_atime != st2.st_atime) e(53);
/* Reading should be done from the current offset. */
if (read(fd1, buf, BUF_SIZE) != 0) e(54);
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(55);
if (read(fd1, buf, BUF_SIZE) != 4) e(56);
if (strcmp(buf, "foo") != 0) e(57);
/* Reading should effect the current file position. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(58);
if (read(fd1, buf, 1) != 1) e(59);
if (*buf != 'f') e(60);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 3) e(61);
if (read(fd1, buf, 1) != 1) e(62);
if (*buf != 'o') e(63);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(64);
if (read(fd1, buf, 1) != 1) e(65);
if (*buf != 'o') e(66);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 5) e(67);
if (read(fd1, buf, 1) != 1) e(68);
if (*buf != '\0') e(69);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(70);
/* Read's at EOF should return 0. */
if (read(fd1, buf, BUF_SIZE) != 0) e(71);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(72);
if (read(fd1, buf, BUF_SIZE) != 0) e(73);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(74);
if (read(fd1, buf, BUF_SIZE) != 0) e(75);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(76);
if (read(fd1, buf, BUF_SIZE) != 0) e(77);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(78);
if (read(fd1, buf, BUF_SIZE) != 0) e(79);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 6) e(80);
/* Writing should not always change the file size. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(81);
if (write(fd1, "ba", 2) != 2) e(82);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 4) e(83);
Stat("bar", &st1);
if (st1.st_size != 6) e(84);
/* Kill the \0 at the end. */
if (lseek(fd1, (off_t) 5, SEEK_SET) != 5) e(85);
if (write(fd1, "x", 1) != 1) e(86);
/* And close the bar. */
if (close(fd1) != 0) e(87);
/* Try some stuff with O_APPEND. Bar contains ``fobaox'' */
if ((fd1 = open("bar", O_RDWR | O_APPEND)) != 3) e(88);
/* No matter what the file position is. Writes should append. */
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(89);
if (write(fd1, "y", 1) != 1) e(90);
Stat("bar", &st1);
if (st1.st_size != (off_t) 7) e(91);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 7) e(92);
if (lseek(fd1, (off_t) 2, SEEK_SET) != 2) e(93);
if (write(fd1, "z", 2) != 2) e(94);
/* The file should contain ``fobaoxyz\0'' == 9 chars long. */
Stat("bar", &st1);
if (st1.st_size != (off_t) 9) e(95);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(96);
/* Reading on a O_APPEND flag should be from the current offset. */
if (lseek(fd1, (off_t) 0, SEEK_SET) != 0) e(97);
if (read(fd1, buf, BUF_SIZE) != 9) e(98);
if (strcmp(buf, "fobaoxyz") != 0) e(99);
if (lseek(fd1, (off_t) 0, SEEK_CUR) != 9) e(100);
if (close(fd1) != 0) e(101);
/* Let's test fifo writes. First blocking. */
if (mkfifo("fifo", 0777) != 0) e(102);
/* Read from fifo but no writer. */
System("rm -rf /tmp/sema.38a");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(103);
system("> /tmp/sema.38a");
system("while test -f /tmp/sema.38a; do sleep 1; done");
errno =0;
if (read(fd1, buf, BUF_SIZE) != 0) e(104);
if (read(fd1, buf, BUF_SIZE) != 0) e(105);
if (read(fd1, buf, BUF_SIZE) != 0) e(106);
if (close(fd1) != 0) e(107);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(108);
while (stat("/tmp/sema.38a", &st1) != 0) sleep(1);
if (close(fd1) != 0) e(109);
unlink("/tmp/sema.38a");
if (wait(&stat_loc) == -1) e(110);
if (stat_loc != 0) e(111); /* Alarm? */
}
/* Read from fifo should wait for writer. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(112);
if (read(fd1, buf, BUF_SIZE) != 10) e(113);
if (strcmp(buf, "Hi reader") != 0) e(114);
if (close(fd1) != 0) e(115);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(116);
sleep(1);
if (write(fd1, "Hi reader", 10) != 10) e(117);
if (close(fd1) != 0) e(118);
if (wait(&stat_loc) == -1) e(119);
if (stat_loc != 0) e(120); /* Alarm? */
}
/* Read from fifo should wait for all writers to close. */
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(121);
if (close(fd1) != 0) e(122);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(123);
sleep(1);
if (close(fd1) != 0) e(124);
if (wait(&stat_loc) == -1) e(125);
if (stat_loc != 0) e(126); /* Alarm? */
}
exit(stat_loc);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(127);
if (read(fd1, buf, BUF_SIZE) != 0) e(128);
if (close(fd1) != 0) e(129);
if (wait(&stat_loc) == -1) e(130);
if (stat_loc != 0) e(131); /* Alarm? */
}
/* PIPE_BUF has to have a nice value. */
if (PIPE_BUF < 5) e(132);
if (BUF_SIZE < 1000) e(133);
/* Writes of blocks smaller than PIPE_BUF should be atomic. */
System("rm -rf /tmp/sema.38b;> /tmp/sema.38b");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(134);
for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
system("while test -f /tmp/sema.38b; do sleep 1; done");
if (close(fd1) != 0) e(135);
exit(0);
default:
if ((fd1 = open("fifo", O_WRONLY)) != 3) e(136);
for (i = 0; i < 100; i++) write(fd1, "1234 ", 5);
while (stat("/tmp/sema.38b", &st1) == 0) sleep(1);
if (close(fd1) != 0) e(137);
if (wait(&stat_loc) == -1) e(138);
if (stat_loc != 0) e(139); /* Alarm? */
}
exit(stat_loc);
default:
if ((fd1 = open("fifo", O_RDONLY)) != 3) e(140);
i = 0;
memset(buf, '\0', BUF_SIZE);
/* Read buffer full or till EOF. */
do {
j = read(fd1, buf + i, BUF_SIZE - i);
if (j > 0) {
if (j % 5 != 0) e(141);
i += j;
}
} while (j > 0 && i < 1000);
/* Signal the children to close write ends. This should not be */
/* Necessary. But due to a bug in 1.16.6 this is necessary. */
unlink("/tmp/sema.38b");
if (j < 0) e(142);
if (i != 1000) e(143);
if (wait(&stat_loc) == -1) e(144);
if (stat_loc != 0) e(145); /* Alarm? */
/* Check 200 times 1234. */
for (i = 0; i < 200; i++)
if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
if (i != 200) e(146);
if (buf[1000] != '\0') e(147);
if (buf[1005] != '\0') e(148);
if (buf[1010] != '\0') e(149);
if (read(fd1, buf, BUF_SIZE) != 0) e(150);
if (close(fd1) != 0) e(151);
}
/* Read from pipe should wait for writer. */
if (pipe(tube) != 0) e(152);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[1]) != 0) e(153);
if (read(tube[0], buf, BUF_SIZE) != 10) e(154);
if (strcmp(buf, "Hi reader") != 0) e(155);
if (close(tube[0]) != 0) e(156);
exit(0);
default:
if (close(tube[0]) != 0) e(157);
sleep(1);
if (write(tube[1], "Hi reader", 10) != 10) e(158);
if (close(tube[1]) != 0) e(159);
if (wait(&stat_loc) == -1) e(160);
if (stat_loc != 0) e(161); /* Alarm? */
}
/* Read from pipe should wait for all writers to close. */
if (pipe(tube) != 0) e(162);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[0]) != 0) e(163);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[1]) != 0) e(164);
exit(0);
default:
sleep(1);
if (close(tube[1]) != 0) e(165);
if (wait(&stat_loc) == -1) e(166);
if (stat_loc != 0) e(167); /* Alarm? */
}
exit(stat_loc);
default:
if (close(tube[1]) != 0) e(168);
if (read(tube[0], buf, BUF_SIZE) != 0) e(169);
if (close(tube[0]) != 0) e(170);
if (wait(&stat_loc) == -1) e(171);
if (stat_loc != 0) e(172); /* Alarm? */
}
/* Writes of blocks smaller than PIPE_BUF should be atomic. */
System("rm -rf /tmp/sema.38c;> /tmp/sema.38c");
if (pipe(tube) != 0) e(173);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if (close(tube[0]) != 0) e(174);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
system("while test -f /tmp/sema.38c; do sleep 1; done");
if (close(tube[1]) != 0) e(175);
exit(0);
default:
for (i = 0; i < 100; i++) write(tube[1], "1234 ", 5);
while (stat("/tmp/sema.38c", &st1) == 0) sleep(1);
if (close(tube[1]) != 0) e(176);
if (wait(&stat_loc) == -1) e(177);
if (stat_loc != 0) e(178); /* Alarm? */
}
exit(stat_loc);
default:
i = 0;
if (close(tube[1]) != 0) e(179);
memset(buf, '\0', BUF_SIZE);
do {
j = read(tube[0], buf + i, BUF_SIZE - i);
if (j > 0) {
if (j % 5 != 0) e(180);
i += j;
} else
break; /* EOF seen. */
} while (i < 1000);
unlink("/tmp/sema.38c");
if (j < 0) e(181);
if (i != 1000) e(182);
if (close(tube[0]) != 0) e(183);
if (wait(&stat_loc) == -1) e(184);
if (stat_loc != 0) e(185); /* Alarm? */
/* Check 200 times 1234. */
for (i = 0; i < 200; i++)
if (strncmp(buf + (i * 5), "1234 ", 5) != 0) break;
if (i != 200) e(186);
}
}
void test38b()
{
int fd;
char buf[32];
int i, fd, stat_loc;
char buf[BUF_SIZE];
char buf2[BUF_SIZE];
struct stat st;
subtest = 2;
/* Test file called ``file''. */
System("echo 'Hallo!' > file");
/* Check dup2() call with the same fds. Should have no effect. */
if ((fd = open("file", O_RDONLY)) != 3) e(1);
if (read(fd, buf, 2) != 2) e(2);
if (strncmp(buf, "Ha", 2) != 0) e(3);
if (dup2(fd, fd) != fd) e(4);
if (read(fd, buf, 2) != 2) e(5);
if (strncmp(buf, "ll", 2) != 0) e(6);
if (dup2(fd, fd) != fd) e(7);
if (read(fd, buf, 2) != 2) e(8);
if (strncmp(buf, "o!", 2) != 0) e(9);
if (close(fd) != 0) e(10);
/* If dup2() call fails, the fildes2 argument has to stay open. */
if ((fd = open("file", O_RDONLY)) != 3) e(11);
if (read(fd, buf, 2) != 2) e(12);
if (strncmp(buf, "Ha", 2) != 0) e(13);
if (dup2(OPEN_MAX + 3, fd) != -1) e(14);
if (errno != EBADF) e(15);
if (read(fd, buf, 2) != 2) e(16);
if (strncmp(buf, "ll", 2) != 0) e(17);
if (dup2(-4, fd) != -1) e(18);
if (errno != EBADF) e(19);
if (read(fd, buf, 2) != 2) e(20);
if (strncmp(buf, "o!", 2) != 0) e(21);
if (close(fd) != 0) e(22);
System("rm -rf ../DIR_38/*");
/* Lets try sequential writes. */
system("rm -rf /tmp/sema.38d");
System("> testing");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(1);
if (write(fd, "one ", 4) != 4) e(2);
if (close(fd) != 0) e(3);
system("> /tmp/sema.38d");
system("while test -f /tmp/sema.38d; do sleep 1; done");
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(4);
if (write(fd, "three ", 6) != 6) e(5);
if (close(fd) != 0) e(6);
system("> /tmp/sema.38d");
exit(0);
default:
while (stat("/tmp/sema.38d", &st) != 0) sleep(1);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(7);
if (write(fd, "two ", 4) != 4) e(8);
if (close(fd) != 0) e(9);
unlink("/tmp/sema.38d");
while (stat("/tmp/sema.38d", &st) != 0) sleep(1);
if ((fd = open("testing", O_WRONLY | O_APPEND)) != 3) e(10);
if (write(fd, "four", 5) != 5) e(11);
if (close(fd) != 0) e(12);
if (wait(&stat_loc) == -1) e(13);
if (stat_loc != 0) e(14); /* The alarm went off? */
unlink("/tmp/sema.38d");
}
if ((fd = open("testing", O_RDONLY)) != 3) e(15);
if (read(fd, buf, BUF_SIZE) != 19) e(16);
if (strcmp(buf, "one two three four") != 0) e(17);
if (close(fd) != 0) e(18);
/* Non written bytes in regular files should be zero. */
memset(buf2, '\0', BUF_SIZE);
if ((fd = open("bigfile", O_RDWR | O_CREAT, 0644)) != 3) e(19);
if (lseek(fd, (off_t) 102400, SEEK_SET) != (off_t) 102400L) e(20);
if (read(fd, buf, BUF_SIZE) != 0) e(21);
if (write(fd, ".", 1) != 1) e(22);
Stat("bigfile", &st);
if (st.st_size != (off_t) 102401) e(23);
if (lseek(fd, (off_t) 0, SEEK_SET) != 0) e(24);
for (i = 0; i < 102400 / BUF_SIZE; i++) {
if (read(fd, buf, BUF_SIZE) != BUF_SIZE) e(25);
if (memcmp(buf, buf2, BUF_SIZE) != 0) e(26);
}
if (close(fd) != 0) e(27);
}
void test38c()
{
int i;
{ /* Test correct error behavior. */
char buf[BUF_SIZE];
int fd, tube[2], stat_loc;
struct stat st;
pid_t pid;
#ifdef SIGACTION
struct sigaction act, oact;
#else
#if _ANSI
void (*oldfunc) (int);
#else
void (*oldfunc) ();
#endif
#endif
subtest = 3;
System("rm -rf ../DIR_38/*");
/* Check bad arguments to dup() and dup2(). */
for (i = -OPEN_MAX; i < OPEN_MAX * 2; i++) {
/* To test if writing processes on closed pipes are signumbered. */
#ifdef SIGACTION
act.sa_handler = setsignumber;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGPIPE, &act, &oact) != 0) e(1);
#else
oldfunc = signal(SIGPIPE, setsignumber);
#endif
/* ``i'' is a valid and open fd. */
if (i >= 0 && i < 3) continue;
/* If ``i'' is a valid fd it is not open. */
if (dup(i) != -1) e(1);
if (errno != EBADF) e(2);
/* ``i'' Is OPEN_MAX. */
if (i == OPEN_MAX) {
if (dup2(0, i) != -1) e(3);
if (errno != EINVAL) e(4);
}
/* ``i'' Is out of range. */
if (i < 0 || i > OPEN_MAX) {
if (dup2(0, i) != -1) e(5);
if (errno != EBADF) e(6);
}
/* Non valid file descriptors should be an error. */
for (fd = -111; fd < 0; fd++) {
errno = 0;
if (read(fd, buf, BUF_SIZE) != -1) e(2);
if (errno != EBADF) e(3);
}
for (fd = 3; fd < 111; fd++) {
errno = 0;
if (read(fd, buf, BUF_SIZE) != -1) e(4);
if (errno != EBADF) e(5);
}
for (fd = -111; fd < 0; fd++) {
errno = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(6);
if (errno != EBADF) e(7);
}
for (fd = 3; fd < 111; fd++) {
errno = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(8);
if (errno != EBADF) e(9);
}
System("rm -rf ../DIR_38/*");
/* Writing a pipe with no readers should trigger SIGPIPE. */
if (pipe(tube) != 0) e(10);
close(tube[0]);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
signumber = 0;
if (write(tube[1], buf, BUF_SIZE) != -1) e(11);
if (errno != EPIPE) e(12);
if (signumber != SIGPIPE) e(13);
if (close(tube[1]) != 0) e(14);
exit(0);
default:
close(tube[1]);
if (wait(&stat_loc) == -1) e(15);
if (stat_loc != 0) e(16); /* Alarm? */
}
/* Writing a fifo with no readers should trigger SIGPIPE. */
System("> /tmp/sema.38e");
if (mkfifo("fifo", 0666) != 0) e(17);
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
if ((fd = open("fifo", O_WRONLY)) != 3) e(18);
system("while test -f /tmp/sema.38e; do sleep 1; done");
signumber = 0;
if (write(fd, buf, BUF_SIZE) != -1) e(19);
if (errno != EPIPE) e(20);
if (signumber != SIGPIPE) e(21);
if (close(fd) != 0) e(22);
exit(0);
default:
if ((fd = open("fifo", O_RDONLY)) != 3) e(23);
if (close(fd) != 0) e(24);
unlink("/tmp/sema.38e");
if (wait(&stat_loc) == -1) e(25);
if (stat_loc != 0) e(26); /* Alarm? */
}
#ifdef SIGACTION
/* Restore normal (re)action to SIGPIPE. */
if (sigaction(SIGPIPE, &oact, NULL) != 0) e(27);
#else
signal(SIGPIPE, oldfunc);
#endif
/* Read from fifo should return -1 and set errno to EAGAIN. */
System("rm -rf /tmp/sema.38[fgh]");
switch (fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
system("while test ! -f /tmp/sema.38f; do sleep 1; done");
System("rm -rf /tmp/sema.38f");
if ((fd = open("fifo", O_WRONLY | O_NONBLOCK)) != 3) e(28);
close(creat("/tmp/sema.38g", 0666));
system("while test ! -f /tmp/sema.38h; do sleep 1; done");
if (close(fd) != 0) e(38);
System("rm -rf /tmp/sema.38h");
exit(0);
default:
if ((fd = open("fifo", O_RDONLY | O_NONBLOCK)) != 3) e(30);
close(creat("/tmp/sema.38f", 0666));
system("while test ! -f /tmp/sema.38g; do sleep 1; done");
System("rm -rf /tmp/sema.38g");
if (read(fd, buf, BUF_SIZE) != -1) e(31);
if (errno != EAGAIN) e(32);
if (read(fd, buf, BUF_SIZE) != -1) e(33);
if (errno != EAGAIN) e(34);
if (read(fd, buf, BUF_SIZE) != -1) e(35);
if (errno != EAGAIN) e(36);
close(creat("/tmp/sema.38h", 0666));
while (stat("/tmp/sema.38h", &st) == 0) sleep(1);
if (read(fd, buf, BUF_SIZE) != 0) e(37);
if (close(fd) != 0) e(38);
if (wait(&stat_loc) == -1) e(39);
if (stat_loc != 0) e(40); /* Alarm? */
}
System("rm -rf fifo");
/* If a read is interrupted by a SIGNAL. */
if (pipe(tube) != 0) e(41);
switch (pid = fork()) {
case -1: printf("Can't fork\n"); break;
case 0:
alarm(20);
#ifdef SIGACTION
act.sa_handler = setsignumber;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (sigaction(SIGUSR1, &act, &oact) != 0) e(42);
#else
oldfunc = signal(SIGUSR1, setsignumber);
#endif
if (read(tube[0], buf, BUF_SIZE) != -1) e(43);
if (errno != EINTR) e(44);
if (signumber != SIGUSR1) e(45);
#ifdef SIGACTION
/* Restore normal (re)action to SIGPIPE. */
if (sigaction(SIGUSR1, &oact, NULL) != 0) e(46);
#else
signal(SIGUSR1, oldfunc);
#endif
close(tube[0]);
close(tube[1]);
exit(0);
default:
/* The sleep 1 should give the child time to start the read. */
sleep(1);
close(tube[0]);
kill(pid, SIGUSR1);
wait(&stat_loc);
if (stat_loc != 0) e(47); /* Alarm? */
close(tube[1]);
}
}
void setsignumber(signum)
int signum;
{
signumber = signum;
}
void e(n)

File diff suppressed because it is too large Load diff