📄 test17.c
字号:
/* 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> /* type defs */
#include <sys/stat.h> /* struct stat */
#include <sys/wait.h>
#include <errno.h> /* the error-numbers */
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <utime.h>
#include <stdio.h>
#define NOCRASH 1 /* test11(), 2nd pipe */
#define PDPNOHANG 1 /* test03(), write_standards() */
#define MAXERR 2
#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 /* max number of bytes to be written on pipe */
#define MAXOPEN 17 /* maximum number of extra open files */
#define MAXLINK 0177 /* maximum number of links per file */
#define LINKCOUNT 5
#define MASK 0777 /* selects lower nine bits */
#define END_FILE 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"
#define READ "read"
#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 errct;
char *file[];
char *fnames[];
char *dir[];
/* "decl.c", created by Rene Montsma and Menno Wilcke */
/* Used in open_alot, close_alot */
char *file[20] = {"f0", "f1", "f2", "f3", "f4", "f5", "f6",
"f7", "f8", "f9", "f10", "f11", "f12", "f13",
"f14", "f15", "f16", "f17", "f18", "f19"}, *fnames[8] = {"---", "--x", "-w-", "-wx", "r--",
"r-x", "rw-", "rwx"}, *dir[8] = {"d---", "d--x", "d-w-", "d-wx", "dr--", "dr-x",
"drw-", "drwx"};
/* Needed for easy creating and deleting of directories */
/* "test.c", created by Rene Montsma and Menno Wilcke */
_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test, (int mask));
_PROTOTYPE(void test01, (void));
_PROTOTYPE(void test02, (void));
_PROTOTYPE(void test08, (void));
_PROTOTYPE(void test09, (void));
_PROTOTYPE(void test10, (void));
_PROTOTYPE(int link_alot, (char *bigboss));
_PROTOTYPE(int unlink_alot, (int number));
_PROTOTYPE(void get_new, (char name []));
_PROTOTYPE(void test11, (void));
_PROTOTYPE(void comp_stats, (struct stat *stbf1, struct stat *stbf2));
_PROTOTYPE(void comp_inodes, (int m, int m1));
_PROTOTYPE(void e, (char *string));
_PROTOTYPE(void nlcr, (void));
_PROTOTYPE(void str, (char *s));
_PROTOTYPE(void err, (int number, char *scall, char *name));
_PROTOTYPE(void make_and_fill_dirs, (void));
_PROTOTYPE(void put_file_in_dir, (char *dirname, int mode));
_PROTOTYPE(void init_array, (char *a));
_PROTOTYPE(void clear_array, (char *b));
_PROTOTYPE(int comp_array, (char *a, char *b, int range));
_PROTOTYPE(void try_close, (int filedes, char *name));
_PROTOTYPE(void try_unlink, (char *fname));
_PROTOTYPE(void Remove, (int fdes, char *fname));
_PROTOTYPE(int get_mode, (char *name));
_PROTOTYPE(void check, (char *scall, int number));
_PROTOTYPE(void put, (int nr));
_PROTOTYPE(int open_alot, (void));
_PROTOTYPE(int close_alot, (int number));
_PROTOTYPE(void clean_up_the_mess, (void));
_PROTOTYPE(void chmod_8_dirs, (int sw));
_PROTOTYPE(void quit, (void));
/*****************************************************************************
* TEST *
****************************************************************************/
int main(argc, argv)
int argc;
char *argv[];
{
int n, mask;
sync();
if (geteuid() == 0 || getuid() == 0) {
printf("Test 17 cannot run as root; test aborted\n");
exit(1);
}
system("rm -rf DIR_18; mkdir DIR_18");
chdir("DIR_18");
mask = (argc == 2 ? atoi(argv[1]) : 0xFFFF);
if (fork()) {
printf("Test 17 ");
fflush(stdout);
wait(&n);
clean_up_the_mess();
quit();
} else {
test(mask);
exit(0);
}
return(-1); /* impossible */
}
void test(mask)
int mask;
{
umask(0); /* not honest, but i always forget */
if (mask & 00001) test01();
if (mask & 00002) make_and_fill_dirs();
if (mask & 00004) test02();
if (mask & 00010) test08();
if (mask & 00020) test09();
if (mask & 00040) test10();
if (mask & 00100) test11();
umask(022);
} /* test */
/* "t1.c" created by Rene Montsma and Menno Wilcke */
/*****************************************************************************
* test UMASK *
****************************************************************************/
void test01()
{
int oldvalue, newvalue, tempvalue;
int nr;
if ((oldvalue = umask(0777)) != 0) err(0, UMASK, NIL);
/* 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) err(1, UMASK, "illegal");
if (oldvalue == newvalue) err(11, UMASK, "not change mask");
if ((tempvalue = umask(0)) != 0) err(2, UMASK, "values");
/* Now test all possible modes of umask on a file */
for (newvalue = MASK; newvalue >= 0; newvalue -= 0111) {
tempvalue = umask(newvalue);
if (tempvalue != oldvalue) {
err(1, UMASK, "illegal");
break; /* no use trying more */
} else if ((nr = creat("file01", 0777)) < 0)
err(5, CREAT, "'file01'");
else {
try_close(nr, "'file01'");
if (get_mode("file01") != (MASK & ~newvalue))
err(7, UMASK, "mode computed");
try_unlink("file01");
}
oldvalue = newvalue;
}
/* The loop has terminated with umask(0) */
if ((tempvalue = umask(0)) != 0)
err(7, UMASK, "umask may influence rest of tests!");
} /* test01 */
/*****************************************************************************
* test CREAT *
****************************************************************************/
void test02()
{
int n, n1, mode;
char a[ARSIZE], b[ARSIZE];
struct stat stbf1;
mode = 0;
/* Create twenty files, check filedes */
for (n = 0; n < MAXOPEN; n++) {
if (creat(file[n], mode) != FF + n)
err(13, CREAT, file[n]);
else {
if (get_mode(file[n]) != mode)
err(7, CREAT, "mode set while creating many files");
/* 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) err(5, CHMOD, file[n]);
}
mode = (mode + 0100) % 01000;
}
/* Already twenty files opened; opening another has to fail */
if (creat("file02", 0777) != FAIL)
err(9, CREAT, "created");
else
check(CREAT, EMFILE);
/* Close all files: seems blunt, but it isn't because we've *
* checked all fd's already */
if ((n = close_alot(MAXOPEN)) < MAXOPEN) err(5, CLOSE, "MAXOPEN files");
/* Creat 1 file twice; check */
if ((n = creat("file02", 0777)) < 0)
err(5, CREAT, "'file02'");
else {
init_array(a);
if (write(n, a, ARSIZE) != ARSIZE) err(1, WRITE, "bad");
if ((n1 = creat("file02", 0755)) < 0) /* receate 'file02' */
err(5, CREAT, "'file02' (2nd time)");
else {
/* Fd should be at the top after recreation */
if (lseek(n1, 0L, SEEK_END) != 0)
err(11, CREAT, "not truncate file by recreation");
else {
/* Try to write on recreated file */
clear_array(b);
if (lseek(n1, 0L, SEEK_SET) != 0)
err(5, LSEEK, "to top of 2nd fd 'file02'");
if (write(n1, a, ARSIZE) != ARSIZE)
err(1, WRITE, "(2) bad");
/* In order to read we've to close and open again */
try_close(n1, "'file02' (2nd creation)");
if ((n1 = open("file02", RW)) < 0)
err(5, OPEN, "'file02' (2nd recreation)");
/* Continue */
if (lseek(n1, 0L, SEEK_SET) != 0)
err(5, LSEEK, "to top 'file02'(2nd fd) (2)");
if (read(n1, b, ARSIZE) != ARSIZE)
err(1, READ, "wrong");
if (comp_array(a, b, ARSIZE) != OK) err(11, CREAT,
"not really truncate file by recreation");
}
if (get_mode("file02") != 0777)
err(11, CREAT, "not maintain mode by recreation");
try_close(n1, "recreated 'file02'");
}
Remove(n, "file02");
}
/* Give 'creat' wrong input: dir not searchable */
if (creat("drw-/file02", 0777) != FAIL)
err(4, CREAT, "'drw-'");
else
check(CREAT, EACCES);
/* Dir not writable */
if (creat("dr-x/file02", 0777) != FAIL)
err(12, CREAT, "'dr-x/file02'");
else
check(CREAT, EACCES);
/* File not writable */
if (creat("drwx/r-x", 0777) != FAIL)
err(11, CREAT, "recreate non-writable file");
else
check(CREAT, EACCES);
/* Try to creat a dir */
if ((n = creat("dir", 040777)) != FAIL) {
if (fstat(n, &stbf1) != OK)
err(5, FSTAT, "'dir'");
else if (stbf1.st_mode != (mode_t) 0100777)
/* cast because mode is negative :-( */
err(11, CREAT, "'creat' a new directory");
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)
err(11, CREAT, "create an existing dir!");
else
check(CREAT, EISDIR);
} /* test02 */
void test08()
{
/* Test chdir to searchable dir */
if (chdir("drwx") != OK)
err(5, CHDIR, "to accessible dir");
else if (chdir("..") != OK)
err(11, CHDIR, "not return to '..'");
/* Check the chdir(".") and chdir("..") mechanism */
if (chdir("drwx") != OK)
err(5, CHDIR, "to 'drwx'");
else {
if (chdir(".") != OK) err(5, CHDIR, "to working dir (.)");
/* If we still are in 'drwx' , we should be able to access *
* file 'rwx'. */
if (access("rwx", 0) != OK) err(5, CHDIR, "rightly to '.'");
/* Try to return to previous dir ('/' !!) */
if (chdir("././../././d--x/../d--x/././..") != OK)
err(5, CHDIR, "to motherdir (..)");
/* Check whether we are back in '/' */
if (chdir("d--x") != OK) err(5, CHDIR, "rightly to a '..'");
}
/* Return to '..' */
if (chdir("..") != OK) err(5, CHDIR, "to '..'");
if (chdir("././././drwx") != OK)
err(11, CHDIR, "not follow a path");
else if (chdir("././././..") != OK)
err(11, CHDIR, "not return to path");
/* Try giving chdir wrong parameters */
if (chdir("drwx/rwx") != FAIL)
err(11, CHDIR, "chdir to a file");
else
check(CHDIR, ENOTDIR);
if (chdir("drw-") != FAIL)
err(4, CHDIR, "'/drw-'");
else
check(CHDIR, EACCES);
/* To be sure: return to root */
/* If (chdir("/") != OK) err(5, CHDIR, "to '/' (2nd time)"); */
} /* test08 */
/* New page */
/*****************************************************************************
* test CHMOD *
****************************************************************************/
void test09()
{
int n;
/* Prepare file09 */
if ((n = creat("drwx/file09", 0644)) != FF) err(5, CREAT, "'drwx/file09'");
try_close(n, "'file09'");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -