minix/test/test18.c

1124 lines
27 KiB
C
Raw Normal View History

2005-04-21 16:53:53 +02:00
/* test 18 */
/* Comment on usage and program: ark!/mnt/rene/prac/os/unix/comment.changes */
/* "const.h", created by Rene Montsma and Menno Wilcke */
#include <sys/types.h> /* needed in struct stat */
#include <sys/stat.h> /* struct stat */
#include <sys/wait.h>
#include <errno.h> /* the error-numbers */
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <limits.h>
2010-01-08 14:40:34 +01:00
#include <assert.h>
#include <sys/uio.h>
2005-04-21 16:53:53 +02:00
#define NOCRASH 1 /* test11(), 2nd pipe */
#define PDPNOHANG 1 /* test03(), write_standards() */
#define MAXERR 5
#define USER_ID 12
#define GROUP_ID 1
#define FF 3 /* first free filedes. */
#define USER 1 /* uid */
#define GROUP 0 /* gid */
#define ARSIZE 256 /* array size */
#define PIPESIZE 3584 /* maxnumber of bytes to be written on pipe */
#define MAXOPEN (OPEN_MAX-3) /* maximum number of extra open files */
2005-04-21 16:53:53 +02:00
#define MAXLINK 0177 /* maximum number of links per file */
#define MASK 0777 /* selects lower nine bits */
#define READ_EOF 0 /* returned by read-call at eof */
#define OK 0
#define FAIL -1
#define R 0 /* read (open-call) */
#define W 1 /* write (open-call) */
#define RW 2 /* read & write (open-call) */
#define RWX 7 /* read & write & execute (mode) */
#define NIL ""
#define UMASK "umask"
#define CREAT "creat"
#define WRITE "write"
2010-01-08 14:40:34 +01:00
#define WRITEV "writev"
2005-04-21 16:53:53 +02:00
#define READ "read"
2010-01-08 14:40:34 +01:00
#define READV "readv"
2005-04-21 16:53:53 +02:00
#define OPEN "open"
#define CLOSE "close"
#define LSEEK "lseek"
#define ACCESS "access"
#define CHDIR "chdir"
#define CHMOD "chmod"
#define LINK "link"
#define UNLINK "unlink"
#define PIPE "pipe"
#define STAT "stat"
#define FSTAT "fstat"
#define DUP "dup"
#define UTIME "utime"
int max_error = 2;
#include "common.h"
2005-04-21 16:53:53 +02:00
/* "decl.c", created by Rene Montsma and Menno Wilcke */
/* Used in open_alot, close_alot */
char *file[MAXOPEN];
char *fnames[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"},
*dir[8] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", "drw-", "drwx"};
2005-04-21 16:53:53 +02:00
/* Needed for easy creating and deleting of directories */
/* "test.c", created by Rene Montsma and Menno Wilcke */
int main(int argc, char **argv);
void test(void);
void test01(void);
void test02(void);
void test03(void);
void write_standards(int filedes, char a []);
void test04(void);
void read_standards(int filedes, char a []);
void read_more(int filedes, char a []);
void test05(void);
void try_open(char *fname, int mode, int test);
void test06(void);
void test07(void);
void access_standards(void);
void test08(void);
static int iovec_is_equal(struct iovec *x, struct iovec *y, size_t
size);
static size_t iovec_setup(int pattern, struct iovec *iovec, char
*buffer, int count);
static int power(int base, int exponent);
void try_access(char *fname, int mode, int test);
void make_and_fill_dirs(void);
void put_file_in_dir(char *dirname, int mode);
void init_array(char *a);
void clear_array(char *b);
int comp_array(char *a, char *b, int range);
void try_close(int filedes, char *name);
void try_unlink(char *fname);
void Remove(int fdes, char *fname);
int get_mode(char *name);
void check(char *scall, int number);
void put(int nr);
int open_alot(void);
int close_alot(int number);
void clean_up_the_mess(void);
void chmod_8_dirs(int sw);
2005-04-21 16:53:53 +02:00
/*****************************************************************************
* TEST *
****************************************************************************/
int main(int argc, char **argv)
2005-04-21 16:53:53 +02:00
{
int n, i;
pid_t child;
start(18);
/* Create filenames for MAXOPEN files, the *file[] array. */
for(i = 0; i < MAXOPEN; i++) {
if(asprintf(&file[i], "file%d", i) == -1) {
fprintf(stderr, "asprintf failed\n");
quit();
}
}
2005-04-21 16:53:53 +02:00
subtest = 0;
child = fork();
if (child == -1) {
e(1);
quit();
} else if (child == 0) {
test();
return(0);
} else {
2005-04-21 16:53:53 +02:00
wait(&n);
clean_up_the_mess();
quit();
}
return(-1);
2005-04-21 16:53:53 +02:00
}
void test()
{
umask(0); /* not honest, but i always forget */
test01();
make_and_fill_dirs();
test02();
test03();
test04();
test05();
test06();
test07();
2010-01-08 14:40:34 +01:00
test08();
2005-04-21 16:53:53 +02:00
umask(022);
} /* test */
/* "t1.c" created by Rene Montsma and Menno Wilcke */
/*****************************************************************************
* test UMASK *
****************************************************************************/
void test01()
{
int oldvalue, newvalue, tempvalue;
int nr;
subtest = 1;
if ((oldvalue = umask(0777)) != 0) e(1);
2005-04-21 16:53:53 +02:00
/* Special test: only the lower 9 bits (protection bits) may part- *
* icipate. ~0777 means: 111 000 000 000. Giving this to umask must*
* not change any value. */
if ((newvalue = umask(~0777)) != 0777) e(2);
if (oldvalue == newvalue) e(3);
2005-04-21 16:53:53 +02:00
if ((tempvalue = umask(0)) != 0) e(4);
2005-04-21 16:53:53 +02:00
/* Now test all possible modes of umask on a file */
for (newvalue = MASK; newvalue >= 0; newvalue -= 0111) {
tempvalue = umask(newvalue);
if (tempvalue != oldvalue) {
e(5);
2005-04-21 16:53:53 +02:00
break; /* no use trying more */
} else if ((nr = creat("file01", 0777)) < 0)
e(6);
2005-04-21 16:53:53 +02:00
else {
try_close(nr, "'file01'");
if (get_mode("file01") != (MASK & ~newvalue)) e(7);
2005-04-21 16:53:53 +02:00
try_unlink("file01");
}
oldvalue = newvalue;
}
/* The loop has terminated with umask(0) */
if ((tempvalue = umask(0)) != 0) e(8);
2005-04-21 16:53:53 +02:00
} /* test01 */
/*****************************************************************************
* test CREAT *
****************************************************************************/
void test02()
{
int n, n1, mode;
char a[ARSIZE], b[ARSIZE];
struct stat stbf1;
subtest = 2;
2005-04-21 16:53:53 +02:00
mode = 0;
/* Create MAXOPEN files, check filedes */
2005-04-21 16:53:53 +02:00
for (n = 0; n < MAXOPEN; n++) {
if (creat(file[n], mode) != FF + n)
e(1);
2005-04-21 16:53:53 +02:00
else {
if (get_mode(file[n]) != mode) e(2);
2005-04-21 16:53:53 +02:00
/* Change mode of file to standard mode, we want to *
* use a lot (20) of files to be opened later, see *
* open_alot(), close_alot(). */
if (chmod(file[n], 0700) != OK) e(3);
2005-04-21 16:53:53 +02:00
}
mode = (mode + 0100) % 01000;
}
/* Already twenty files opened; opening another has to fail */
if (creat("file02", 0777) != FAIL) e(4);
2005-04-21 16:53:53 +02:00
else
if (errno != EMFILE) e(5);;
2005-04-21 16:53:53 +02:00
/* Close all files: seems blunt, but it isn't because we've *
* checked all fd's already */
if ((n = close_alot(MAXOPEN)) < MAXOPEN) e(6);
2005-04-21 16:53:53 +02:00
/* Creat 1 file twice; check */
if ((n = creat("file02", 0777)) < 0) e(7);
2005-04-21 16:53:53 +02:00
else {
init_array(a);
if (write(n, a, ARSIZE) != ARSIZE) e(8);
2005-04-21 16:53:53 +02:00
if ((n1 = creat("file02", 0755)) < 0) e(9);
2005-04-21 16:53:53 +02:00
else {
/* Fd should be at the top after recreation */
if (lseek(n1, 0L, SEEK_END) != 0) e(10);
2005-04-21 16:53:53 +02:00
else {
/* Try to write on recreated file */
clear_array(b);
if (lseek(n1, 0L, SEEK_SET) != 0) e(11);
if (write(n1, a, ARSIZE) != ARSIZE) e(12);
2005-04-21 16:53:53 +02:00
/* In order to read we've to close and open again */
try_close(n1, "'file02' (2nd creation)");
if ((n1 = open("file02", RW)) < 0) e(13);
2005-04-21 16:53:53 +02:00
/* Continue */
if (lseek(n1, 0L, SEEK_SET) != 0) e(14);
if (read(n1, b, ARSIZE) != ARSIZE) e(15);
2005-04-21 16:53:53 +02:00
if (comp_array(a, b, ARSIZE) != OK) e(16);
2005-04-21 16:53:53 +02:00
}
if (get_mode("file02") != 0777) e(17);
2005-04-21 16:53:53 +02:00
try_close(n1, "recreated 'file02'");
}
Remove(n, "file02");
}
/* Give 'creat' wrong input: dir not searchable */
if (creat("drw-/file02", 0777) != FAIL) e(18);
2005-04-21 16:53:53 +02:00
else
if (errno != EACCES) e(19);
2005-04-21 16:53:53 +02:00
/* Dir not writable */
if (creat("dr-x/file02", 0777) != FAIL) e(20);
2005-04-21 16:53:53 +02:00
else
if (errno != EACCES) e(21);
2005-04-21 16:53:53 +02:00
/* File not writable */
if (creat("drwx/r-x", 0777) != FAIL) e(22);
2005-04-21 16:53:53 +02:00
else
if (errno != EACCES) e(23);
2005-04-21 16:53:53 +02:00
/* Try to creat a dir */
if ((n = creat("dir", 040777)) != FAIL) {
if (fstat(n, &stbf1) != OK) e(24);
2005-04-21 16:53:53 +02:00
else if (stbf1.st_mode != (mode_t) 0100777)
/* Cast because mode is negative :-(.
* HACK DEBUG FIXME: this appears to duplicate
* code in test17.c.
*/
e(25);
2005-04-21 16:53:53 +02:00
Remove(n, "dir");
}
/* We don't consider it to be a bug when creat * does not accept
* tricky modes */
/* File is an existing dir */
if (creat("drwx", 0777) != FAIL) e(26);
2005-04-21 16:53:53 +02:00
else
if (errno != EISDIR) e(27);
2005-04-21 16:53:53 +02:00
} /* test02 */
/*****************************************************************************
* test WRITE *
****************************************************************************/
void test03()
{
int n, n1;
int fd[2];
char a[ARSIZE];
subtest = 3;
2005-04-21 16:53:53 +02:00
init_array(a);
/* Test write after a CREAT */
if ((n = creat("file03", 0700)) != FF) e(1);
2005-04-21 16:53:53 +02:00
else {
write_standards(n, a); /* test simple writes, wrong input too */
try_close(n, "'file03'");
}
/* Test write after an OPEN */
if ((n = open("file03", W)) < 0) e(2);
2005-04-21 16:53:53 +02:00
else
write_standards(n, a); /* test simple writes, wrong input too */
/* Test write after a DUP */
if ((n1 = dup(n)) < 0) e(3);
2005-04-21 16:53:53 +02:00
else {
write_standards(n1, a);
try_close(n1, "duplicated fd 'file03'");
}
/* Remove testfile */
Remove(n, "file03");
/* Test write after a PIPE */
if (pipe(fd) < 0) e(4);
2005-04-21 16:53:53 +02:00
else {
write_standards(fd[1], a);
try_close(fd[0], "'fd[0]'");
try_close(fd[1], "'fd[1]'");
}
/* Last test: does write check protections ? */
if ((n = open("drwx/r--", R)) < 0) e(5);
2005-04-21 16:53:53 +02:00
else {
if (write(n, a, ARSIZE) != FAIL) e(6);
2005-04-21 16:53:53 +02:00
else
if (errno != EBADF) e(7);
2005-04-21 16:53:53 +02:00
try_close(n, "'drwx/r--'");
}
} /* test03 */
void write_standards(filedes, a)
int filedes;
char a[];
{
/* Write must return written account of numbers */
if (write(filedes, a, ARSIZE) != ARSIZE) e(80);
2005-04-21 16:53:53 +02:00
/* Try giving 'write' wrong input */
/* Wrong filedes */
if (write(-1, a, ARSIZE) != FAIL) e(81);
2005-04-21 16:53:53 +02:00
else
if (errno != EBADF) e(82);
2005-04-21 16:53:53 +02:00
/* Wrong length (illegal) */
#ifndef PDPNOHANG
if (write(filedes, a, -ARSIZE) != FAIL) e(83);
2005-04-21 16:53:53 +02:00
else
if (errno != EINVAL) e(84);
2005-04-21 16:53:53 +02:00
#endif
} /* write_standards */
/*****************************************************************************
* test READ *
****************************************************************************/
void test04()
{
int n, n1, fd[2];
char a[ARSIZE];
subtest = 4;
2005-04-21 16:53:53 +02:00
/* Test read after creat */
if ((n = creat("file04", 0700)) != FF) e(1);
2005-04-21 16:53:53 +02:00
else {
/* Closing and opening needed before writing */
try_close(n, "'file04'");
if ((n = open("file04", RW)) < 0) e(2);
2005-04-21 16:53:53 +02:00
init_array(a);
if (write(n, a, ARSIZE) != ARSIZE) e(3);
2005-04-21 16:53:53 +02:00
else {
if (lseek(n, 0L, SEEK_SET) != 0) e(4);
2005-04-21 16:53:53 +02:00
read_standards(n, a);
read_more(n, a);
}
try_close(n, "'file04'");
}
/* Test read after OPEN */
if ((n = open("file04", R)) < 0) e(5);
2005-04-21 16:53:53 +02:00
else {
read_standards(n, a);
read_more(n, a);
try_close(n, "'file04'");
}
/* Test read after DUP */
if ((n = open("file04", R)) < 0) e(6);
if ((n1 = dup(n)) < 0) e(7);
2005-04-21 16:53:53 +02:00
else {
read_standards(n1, a);
read_more(n1, a);
try_close(n1, "duplicated fd 'file04'");
}
/* Remove testfile */
Remove(n, "file04");
/* Test read after pipe */
if (pipe(fd) < 0) e(8);
2005-04-21 16:53:53 +02:00
else {
if (write(fd[1], a, ARSIZE) != ARSIZE) {
e(9);
2005-04-21 16:53:53 +02:00
try_close(fd[1], "'fd[1]'");
} else {
try_close(fd[1], "'fd[1]'");
read_standards(fd[0], a);
}
try_close(fd[0], "'fd[0]'");
}
/* Last test: try to read a read-protected file */
if ((n = open("drwx/-wx", W)) < 0) e(10);
2005-04-21 16:53:53 +02:00
else {
if (read(n, a, ARSIZE) != FAIL) e(11);
2005-04-21 16:53:53 +02:00
else
if (errno != EBADF) e(12);
2005-04-21 16:53:53 +02:00
try_close(n, "'/drwx/-wx'");
}
} /* test04 */
void read_standards(filedes, a)
int filedes;
char a[];
{
char b[ARSIZE];
clear_array(b);
if (read(filedes, b, ARSIZE) != ARSIZE) e(85);
else if (comp_array(a, b, ARSIZE) != OK) e(86);
else if (read(filedes, b, ARSIZE) != READ_EOF) e(87);
2005-04-21 16:53:53 +02:00
/* Try giving read wrong input: wrong filedes */
if (read(FAIL, b, ARSIZE) != FAIL) e(88);
2005-04-21 16:53:53 +02:00
else
if (errno != EBADF) e(89);
2005-04-21 16:53:53 +02:00
/* Wrong length */
if (read(filedes, b, -ARSIZE) != FAIL) e(90);
2005-04-21 16:53:53 +02:00
else
if (errno != EINVAL) e(91);
2005-04-21 16:53:53 +02:00
} /* read_standards */
void read_more(filedes, a)
int filedes;
char a[];
/* Separated from read_standards() because the PIPE test * would fail. */
{
int i;
char b[ARSIZE];
if (lseek(filedes, (long) (ARSIZE / 2), SEEK_SET) != ARSIZE / 2) e(92);
2005-04-21 16:53:53 +02:00
clear_array(b);
if (read(filedes, b, ARSIZE) != ARSIZE / 2) e(93);
2005-04-21 16:53:53 +02:00
for (i = 0; i < ARSIZE / 2; i++)
if (b[i] != a[(ARSIZE / 2) + i]) e(94);
2005-04-21 16:53:53 +02:00
}
/*****************************************************************************
* test OPEN/CLOSE *
****************************************************************************/
void test05()
{
int n, n1, mode, fd[2];
char b[ARSIZE];
subtest = 5;
2005-04-21 16:53:53 +02:00
/* Test open after CREAT */
if ((n = creat("file05", 0700)) != FF) e(1);
2005-04-21 16:53:53 +02:00
else {
if ((n1 = open("file05", RW)) != FF + 1) e(2);
2005-04-21 16:53:53 +02:00
try_close(n1, "'file05' (open after creation)");
try_close(n, "'file05'");
if ((n = open("file05", R)) != FF) e(3);
2005-04-21 16:53:53 +02:00
else
try_close(n, "'file05' (open after closing)");
/* Remove testfile */
try_unlink("file05");
}
/* Test all possible modes, try_open not only opens file (sometimes) *
* but closes files too (when opened) */
if ((n = creat("file05", 0700)) < 0) e(6);
2005-04-21 16:53:53 +02:00
else {
try_close(n, "file05");
for (mode = 0; mode <= 0700; mode += 0100) {
if (chmod("file05", mode) != OK) e(7);
2005-04-21 16:53:53 +02:00
if (mode <= 0100) {
try_open("file05", R, FAIL);
try_open("file05", W, FAIL);
try_open("file05", RW, FAIL);
} else if (mode >= 0200 && mode <= 0300) {
try_open("file05", R, FAIL);
try_open("file05", W, FF);
try_open("file05", RW, FAIL);
} else if (mode >= 0400 && mode <= 0500) {
try_open("file05", R, FF);
try_open("file05", W, FAIL);
try_open("file05", RW, FAIL);
} else {
try_open("file05", R, FF);
try_open("file05", W, FF);
try_open("file05", RW, FF);
}
}
}
/* Test opening existing file */
if ((n = open("drwx/rwx", R)) < 0) e(8);
2005-04-21 16:53:53 +02:00
else { /* test close after DUP */
if ((n1 = dup(n)) < 0) e(9);
2005-04-21 16:53:53 +02:00
else {
try_close(n1, "duplicated fd 'drwx/rwx'");
if (read(n1, b, ARSIZE) != FAIL) e(10);
2005-04-21 16:53:53 +02:00
else
if (errno != EBADF) e(11);
2005-04-21 16:53:53 +02:00
if (read(n, b, ARSIZE) == FAIL) e(12);/* should read an eof */
2005-04-21 16:53:53 +02:00
}
try_close(n, "'drwx/rwx'");
}
/* Test close after PIPE */
if (pipe(fd) < 0) e(13);
2005-04-21 16:53:53 +02:00
else {
try_close(fd[1], "duplicated fd 'fd[1]'");
/* Fd[1] really should be closed now; check */
clear_array(b);
if (read(fd[0], b, ARSIZE) != READ_EOF) e(14);
2005-04-21 16:53:53 +02:00
try_close(fd[0], "duplicated fd 'fd[0]'");
}
/* Try to open a non-existing file */
if (open("non-file", R) != FAIL) e(15);
2005-04-21 16:53:53 +02:00
else
if (errno != ENOENT) e(16);
2005-04-21 16:53:53 +02:00
/* Dir does not exist */
if (open("dzzz/file05", R) != FAIL) e(17);
2005-04-21 16:53:53 +02:00
else
if (errno != ENOENT) e(18);
2005-04-21 16:53:53 +02:00
/* Dir is not searchable */
if ((n = open("drw-/rwx", R)) != FAIL) e(19);
2005-04-21 16:53:53 +02:00
else
if (errno != EACCES) e(20);
2005-04-21 16:53:53 +02:00
/* Unlink testfile */
try_unlink("file05");
/* File is not readable */
if (open("drwx/-wx", R) != FAIL) e(21);
2005-04-21 16:53:53 +02:00
else
if (errno != EACCES) e(22);
2005-04-21 16:53:53 +02:00
/* File is not writable */
if (open("drwx/r-x", W) != FAIL) e(23);
2005-04-21 16:53:53 +02:00
else
if (errno != EACCES) e(24);
2005-04-21 16:53:53 +02:00
/* Try opening more than MAXOPEN ('extra' (19-8-85)) files */
if ((n = open_alot()) != MAXOPEN) e(25);
2005-04-21 16:53:53 +02:00
else
/* Maximum # of files opened now, another open should fail
* because * all filedescriptors have already been used. */
if (open("drwx/rwx", RW) != FAIL) e(26);
2005-04-21 16:53:53 +02:00
else
if (errno != EMFILE) e(27);
if (close_alot(n) != n) e(28);
2005-04-21 16:53:53 +02:00
/* Can close make mistakes ? */
if (close(-1) != FAIL) e(29);
2005-04-21 16:53:53 +02:00
else
if (errno != EBADF) e(30);
2005-04-21 16:53:53 +02:00
} /* test05 */
void try_open(fname, mode, test)
int mode, test;
char *fname;
{
int n;
if ((n = open(fname, mode)) != test) e(95);
2005-04-21 16:53:53 +02:00
if (n != FAIL) try_close(n, fname); /* cleanup */
} /* try_open */
/*****************************************************************************
* test LSEEK *
****************************************************************************/
void test06()
{
char a[ARSIZE], b[ARSIZE];
int fd;
subtest = 6;
if ((fd = open("drwx/rwx", RW)) != FF) e(1);
2005-04-21 16:53:53 +02:00
else {
init_array(a);
if (write(fd, a, 10) != 10) e(2);
2005-04-21 16:53:53 +02:00
else {
/* Lseek back to begin file */
if (lseek(fd, 0L, SEEK_SET) != 0) e(3);
else if (read(fd, b, 10) != 10) e(4);
else if (comp_array(a, b, 10) != OK) e(5);
2005-04-21 16:53:53 +02:00
/* Lseek to endoffile */
if (lseek(fd, 0L, SEEK_END) != 10) e(6);
else if (read(fd, b, 1) != READ_EOF) e(7);
2005-04-21 16:53:53 +02:00
/* Lseek beyond file */
if (lseek(fd, 10L, SEEK_CUR) != 20) e(8);
else if (write(fd, a, 10) != 10) e(9);
2005-04-21 16:53:53 +02:00
else {
/* Lseek to begin second write */
if (lseek(fd, 20L, SEEK_SET) != 20) e(10);
if (read(fd, b, 10) != 10) e(11);
else if (comp_array(a, b, 10) != OK) e(12);
2005-04-21 16:53:53 +02:00
}
}
/* Lseek to position before begin of file */
if (lseek(fd, -1L, 0) != FAIL) e(13);
2005-04-21 16:53:53 +02:00
try_close(fd, "'drwx/rwx'");
}
/* Lseek on invalid filediscriptor */
if (lseek(-1, 0L, SEEK_SET) != FAIL) e(14);
2005-04-21 16:53:53 +02:00
else
if (errno != EBADF) e(15);
2005-04-21 16:53:53 +02:00
}
/*****************************************************************************
* test ACCESS *
****************************************************************************/
void test07()
{
subtest = 7;
2005-04-21 16:53:53 +02:00
/* Check with proper parameters */
if (access("drwx/rwx", RWX) != OK) e(1);
2005-04-21 16:53:53 +02:00
if (access("./././drwx/././rwx", 0) != OK) e(2);
2005-04-21 16:53:53 +02:00
/* Check 8 files with 8 different modes on 8 accesses */
if (chdir("drwx") != OK) e(3);
2005-04-21 16:53:53 +02:00
access_standards();
if (chdir("..") != OK) e(4);
2005-04-21 16:53:53 +02:00
/* Check several wrong combinations */
/* File does not exist */
if (access("non-file", 0) != FAIL) e(5);
2005-04-21 16:53:53 +02:00
else
if (errno != ENOENT) e(6);
2005-04-21 16:53:53 +02:00
/* Non-searchable dir */
if (access("drw-/rwx", 0) != FAIL) e(7);
2005-04-21 16:53:53 +02:00
else
if (errno != EACCES) e(8);
2005-04-21 16:53:53 +02:00
/* Searchable dir, but wrong file-mode */
if (access("drwx/--x", RWX) != FAIL) e(9);
2005-04-21 16:53:53 +02:00
else
if (errno != EACCES) e(10);
2005-04-21 16:53:53 +02:00
} /* test07 */
void access_standards()
{
int i, mode = 0;
for (i = 0; i < 8; i++)
if (i == 0)
try_access(fnames[mode], i, OK);
else
try_access(fnames[mode], i, FAIL);
mode++;
for (i = 0; i < 8; i++)
if (i < 2)
try_access(fnames[mode], i, OK);
else
try_access(fnames[mode], i, FAIL);
mode++;
for (i = 0; i < 8; i++)
if (i == 0 || i == 2)
try_access(fnames[mode], i, OK);
else
try_access(fnames[mode], i, FAIL);
mode++;
for (i = 0; i < 8; i++)
if (i < 4)
try_access(fnames[mode], i, OK);
else
try_access(fnames[mode], i, FAIL);
mode++;
for (i = 0; i < 8; i++)
if (i == 0 || i == 4)
try_access(fnames[mode], i, OK);
else
try_access(fnames[mode], i, FAIL);
mode++;
for (i = 0; i < 8; i++)
if (i == 0 || i == 1 || i == 4 || i == 5)
try_access(fnames[mode], i, OK);
else
try_access(fnames[mode], i, FAIL);
mode++;
for (i = 0; i < 8; i++)
if (i % 2 == 0)
try_access(fnames[mode], i, OK);
else
try_access(fnames[mode], i, FAIL);
mode++;
for (i = 0; i < 8; i++) try_access(fnames[mode], i, OK);
} /* access_standards */
void try_access(fname, mode, test)
int mode, test;
char *fname;
{
if (access(fname, mode) != test) e(96);
2005-04-21 16:53:53 +02:00
} /* try_access */
/* Err, make_and_fill_dirs, init_array, clear_array, comp_array,
try_close, try_unlink, Remove, get_mode, check, open_alot,
close_alot, clean_up_the_mess.
*/
2010-01-08 14:40:34 +01:00
/*****************************************************************************
* test READV/WRITEV *
****************************************************************************/
#define TEST8_BUFSZCOUNT 3
#define TEST8_BUFSZMAX 65536
#define TEST8_IOVCOUNT 4
void test08()
{
char buffer_read[TEST8_IOVCOUNT * TEST8_BUFSZMAX];
char buffer_write[TEST8_IOVCOUNT * TEST8_BUFSZMAX];
struct iovec iovec_read[TEST8_IOVCOUNT];
struct iovec iovec_write[TEST8_IOVCOUNT];
int fd, i, j, k, l, m;
ssize_t sz_read, sz_write;
size_t sz_read_exp, sz_read_sum, sz_write_sum;
subtest = 8;
2010-01-08 14:40:34 +01:00
/* try various combinations of buffer sizes */
for (i = 0; i <= TEST8_IOVCOUNT; i++)
for (j = 0; j < power(TEST8_BUFSZCOUNT, i); j++)
for (k = 0; k <= TEST8_IOVCOUNT; k++)
for (l = 0; l < power(TEST8_BUFSZCOUNT, k); l++)
{
/* put data in the buffers */
for (m = 0; m < sizeof(buffer_write); m++)
{
buffer_write[m] = m ^ (m >> 8);
buffer_read[m] = ~buffer_write[m];
}
/* set up the vectors to point to the buffers */
sz_read_sum = iovec_setup(j, iovec_read, buffer_read, i);
sz_write_sum = iovec_setup(l, iovec_write, buffer_write, k);
sz_read_exp = (sz_read_sum < sz_write_sum) ?
sz_read_sum : sz_write_sum;
/* test reading and writing */
if ((fd = open("file08", O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) e(1);
2010-01-08 14:40:34 +01:00
else {
sz_write = writev(fd, iovec_write, k);
if (sz_write != sz_write_sum) e(2);
if (lseek(fd, 0, SEEK_SET) != 0) e(3);
2010-01-08 14:40:34 +01:00
sz_read = readv(fd, iovec_read, i);
if (sz_read != sz_read_exp) e(4);
else {
2010-01-08 14:40:34 +01:00
if (!iovec_is_equal(iovec_read, iovec_write, sz_read))
e(5);
2010-01-08 14:40:34 +01:00
}
/* Remove testfile */
Remove(fd, "file08");
}
}
} /* test08 */
static int iovec_is_equal(struct iovec *x, struct iovec *y, size_t size)
{
int xpos = 0, xvec = 0, ypos = 0, yvec = 0;
/* compare byte by byte */
while (size-- > 0)
{
/* skip over zero-byte buffers and those that have been completed */
while (xpos >= x[xvec].iov_len)
{
xpos -= x[xvec++].iov_len;
assert(xvec < TEST8_IOVCOUNT);
}
while (ypos >= y[yvec].iov_len)
{
ypos -= y[yvec++].iov_len;
assert(yvec < TEST8_IOVCOUNT);
}
/* compare */
if (((char *) x[xvec].iov_base)[xpos++] !=
((char *) y[yvec].iov_base)[ypos++])
return 0;
}
/* no difference found */
return 1;
}
static size_t iovec_setup(int pattern, struct iovec *iovec, char *buffer, int count)
{
static const size_t bufsizes[TEST8_BUFSZCOUNT] = { 0, 1, TEST8_BUFSZMAX };
int i;
size_t sum = 0;
/* the pattern specifies each buffer */
for (i = 0; i < TEST8_IOVCOUNT; i++)
{
iovec->iov_base = buffer;
sum += iovec->iov_len = bufsizes[pattern % TEST8_BUFSZCOUNT];
iovec++;
buffer += TEST8_BUFSZMAX;
pattern /= TEST8_BUFSZCOUNT;
}
return sum;
}
static int power(int base, int exponent)
{
int result = 1;
/* compute base^exponent */
while (exponent-- > 0)
result *= base;
return result;
}
2005-04-21 16:53:53 +02:00
/*****************************************************************************
* *
* MAKE_AND_FILL_DIRS *
* *
*****************************************************************************/
void make_and_fill_dirs()
/* Create 8 dir.'s: "d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x", *
* "drw-", "drwx". * Then create 8 files
* in "drwx", and some needed files in other dirs. */
{
int mode, i;
for (i = 0; i < 8; i++) {
mkdir(dir[i], 0700);
chown(dir[i], USER_ID, GROUP_ID);
}
setuid(USER_ID);
setgid(GROUP_ID);
for (mode = 0; mode < 8; mode++) put_file_in_dir("drwx", mode);
put_file_in_dir("d-wx", RWX);
put_file_in_dir("dr-x", RWX);
put_file_in_dir("drw-", RWX);
chmod_8_dirs(8); /* 8 means; 8 different modes */
} /* make_and_fill_dirs */
void put_file_in_dir(dirname, mode)
char *dirname;
int mode;
/* Fill directory 'dirname' with file with mode 'mode'. */
{
int nr;
if (chdir(dirname) != OK) e(97);
2005-04-21 16:53:53 +02:00
else {
/* Creat the file */
if ((nr = creat(fnames[mode], mode * 0100)) < 0) e(98);
2005-04-21 16:53:53 +02:00
else
try_close(nr, fnames[mode]);
if (chdir("..") != OK) e(99);
2005-04-21 16:53:53 +02:00
}
} /* put_file_in_dir */
/*****************************************************************************
* *
* MISCELLANEOUS *
* *
*(all about arrays, 'try_close', 'try_unlink', 'Remove', 'get_mode') *
* *
*****************************************************************************/
void init_array(a)
char *a;
{
int i;
i = 0;
while (i++ < ARSIZE) *a++ = 'a' + (i % 26);
} /* init_array */
void clear_array(b)
char *b;
{
int i;
i = 0;
while (i++ < ARSIZE) *b++ = '0';
} /* clear_array */
int comp_array(a, b, range)
char *a, *b;
int range;
{
assert(range >= 0 && range <= ARSIZE);
while (range-- && (*a++ == *b++));
if (*--a == *--b)
return(OK);
else
2005-04-21 16:53:53 +02:00
return(FAIL);
} /* comp_array */
void try_close(filedes, name)
int filedes;
char *name;
{
if (close(filedes) != OK) e(100);
2005-04-21 16:53:53 +02:00
} /* try_close */
void try_unlink(fname)
char *fname;
{
if (unlink(fname) != 0) e(101);
2005-04-21 16:53:53 +02:00
} /* try_unlink */
void Remove(fdes, fname)
int fdes;
char *fname;
{
try_close(fdes, fname);
try_unlink(fname);
} /* Remove */
int get_mode(name)
char *name;
{
struct stat stbf1;
if (stat(name, &stbf1) != OK) {
e(102);
2005-04-21 16:53:53 +02:00
return(stbf1.st_mode); /* return a mode which will cause *
* error in the calling function *
* (file/dir bit) */
} else
return(stbf1.st_mode & 07777); /* take last 4 bits */
} /* get_mode */
/*****************************************************************************
* *
* ALOT-functions *
* *
*****************************************************************************/
int open_alot()
{
int i;
for (i = 0; i < MAXOPEN; i++)
if (open(file[i], R) == FAIL) break;
if (i == 0)
e(103);
2005-04-21 16:53:53 +02:00
return(i);
} /* open_alot */
int close_alot(number)
int number;
{
int i, count = 0;
if (number > MAXOPEN) e(104);
2005-04-21 16:53:53 +02:00
else
for (i = FF; i < number + FF; i++)
if (close(i) != OK) count++;
return(number - count); /* return number of closed files */
} /* close_alot */
/*****************************************************************************
* *
* CLEAN UP THE MESS *
* *
*****************************************************************************/
void clean_up_the_mess()
{
int i;
char dirname[6];
/* First remove 'alot' files */
for (i = 0; i < MAXOPEN; i++) try_unlink(file[i]);
/* Unlink the files in dir 'drwx' */
if (chdir("drwx") != OK) e(105);
2005-04-21 16:53:53 +02:00
else {
for (i = 0; i < 8; i++) try_unlink(fnames[i]);
if (chdir("..") != OK) e(106);
2005-04-21 16:53:53 +02:00
}
/* Before unlinking files in some dirs, make them writable */
chmod_8_dirs(RWX);
/* Unlink files in other dirs */
try_unlink("d-wx/rwx");
try_unlink("dr-x/rwx");
try_unlink("drw-/rwx");
/* Unlink dirs */
for (i = 0; i < 8; i++) {
strcpy(dirname, "d");
strcat(dirname, fnames[i]);
/* 'dirname' contains the directoryname */
rmdir(dirname);
}
/* FINISH */
} /* clean_up_the_mess */
void chmod_8_dirs(sw)
int sw; /* if switch == 8, give all different
* mode,else the same mode */
{
int mode;
int i;
if (sw == 8)
mode = 0;
else
mode = sw;
for (i = 0; i < 8; i++) {
chmod(dir[i], 040000 + mode * 0100);
if (sw == 8) mode++;
}
}