⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test20.c

📁 MINIX2.0操作系统源码 MINIX2.0操作系统源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* POSIX test program (20).			Author: Andy Tanenbaum */

/* The following POSIX calls are tested:
 *
 *	opendir()
 *	readdir()
 *	rewinddir()
 *	closedir()
 *	chdir()
 *	getcwd()
 */


#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include <stdio.h>

#define DIR_NULL (DIR*) NULL
#define ITERATIONS         5
#define MAX_FD           100	/* must be large enough to cause error */
#define BUF_SIZE PATH_MAX+20
#define ERR_CODE          -1	/* error return */
#define RD_BUF           200
#define MAX_ERROR          4

char str[] = {"The time has come the walrus said to talk of many things.\n"};
char str2[] = {"Of ships and shoes and sealing wax, of cabbages and kings.\n"};
char str3[] = {"Of why the sea is boiling hot and whether pigs have wings\n"};

int subtest, errct;

_PROTOTYPE(int main, (int argc, char *argv []));
_PROTOTYPE(void test20a, (void));
_PROTOTYPE(void checkdir, (DIR *dirp, int t));
_PROTOTYPE(void test20b, (void));
_PROTOTYPE(void test20c, (void));
_PROTOTYPE(void test20d, (void));
_PROTOTYPE(void test20e, (void));
_PROTOTYPE(void test20f, (void));
_PROTOTYPE(void test20g, (void));
_PROTOTYPE(void test20h, (void));
_PROTOTYPE(void test20i, (void));
_PROTOTYPE(void test20j, (void));
_PROTOTYPE(void e, (int n));
_PROTOTYPE(void quit, (void));

int main(argc, argv)
int argc;
char *argv[];
{

  int i, m = 0xFFFF;

  sync();
  if (geteuid() == 0 || getuid() == 0) {
	printf("Test 20 cannot run as root; test aborted\n");
	exit(1);
  }

  if (argc == 2) m = atoi(argv[1]);
  printf("Test 20 ");
  fflush(stdout);

  system("rm -rf DIR_20; mkdir DIR_20");
  chdir("DIR_20");

  for (i = 0; i < ITERATIONS; i++) {
	if (m & 00001) test20a();	/* test for correct operation */
	if (m & 00002) test20b();	/* test general error handling */
	if (m & 00004) test20c();	/* test for EMFILE error */
	if (m & 00010) test20d();	/* test chdir() and getcwd() */
	if (m & 00020) test20e();	/* test open() */
	if (m & 00040) test20f();	/* test umask(), stat(), fstat() */
	if (m & 00100) test20g();	/* test link() and unlink() */
	if (m & 00200) test20h();	/* test access() */
	if (m & 00400) test20i();	/* test chmod() and chown() */
	if (m & 01000) test20j();	/* test utime() */
  }
  quit();
  return(-1);			/* impossible */
}

void test20a()
{
/* Subtest 1. Correct operation */

  int f1, f2, f3, f4, f5;
  DIR *dirp;

  /* Remove any residue of previous tests. */
  subtest = 1;

  system("rm -rf foo");

  /* Create a directory foo with 5 files in it. */
  mkdir("foo", 0777);
  if ((f1 = creat("foo/f1", 0666)) < 0) e(1);
  if ((f2 = creat("foo/f2", 0666)) < 0) e(2);
  if ((f3 = creat("foo/f3", 0666)) < 0) e(3);
  if ((f4 = creat("foo/f4", 0666)) < 0) e(4);
  if ((f5 = creat("foo/f5", 0666)) < 0) e(5);

  /* Now remove 2 files to create holes in the directory. */
  if (unlink("foo/f2") < 0) e(6);
  if (unlink("foo/f4") < 0) e(7);

  /* Close the files. */
  close(f1);
  close(f2);
  close(f3);
  close(f4);
  close(f5);

  /* Open the directory. */
  dirp = opendir("./foo");
  if (dirp == DIR_NULL) e(6);

  /* Read the 5 files from it. */
  checkdir(dirp, 2); 

  /* Rewind dir and test again. */
  rewinddir(dirp);
  checkdir(dirp, 3);

  /* We're done.  Close the directory stream. */
  if (closedir(dirp) < 0) e(7);

  /* Remove dir for next time. */
  system("rm -rf foo");
}

void checkdir(dirp, t)
DIR *dirp;			/* poinrter to directory stream */
int t;				/* subtest number to use */
{

  int i, f1, f2, f3, f4, f5, dot, dotdot, subt;
  struct dirent *d;
  char *s;

  /* Save subtest number */
  subt = subtest;
  subtest = t;

  /* Clear the counters. */
  f1 = 0;
  f2 = 0;
  f3 = 0;
  f4 = 0;
  f5 = 0;
  dot = 0;
  dotdot = 0;

  /* Read the directory.  It should contain 5 entries, ".", ".." and 3
   * files. */
  for (i = 0; i < 5; i++) {
	d = readdir(dirp);
	if (d == (struct dirent *) NULL) {
		e(1);
		subtest = subt;	/* restore subtest number */
		return;
	}
	s = d->d_name;
	if (strcmp(s, ".") == 0) dot++;
	if (strcmp(s, "..") == 0) dotdot++;
	if (strcmp(s, "f1") == 0) f1++;
	if (strcmp(s, "f2") == 0) f2++;
	if (strcmp(s, "f3") == 0) f3++;
	if (strcmp(s, "f4") == 0) f4++;
	if (strcmp(s, "f5") == 0) f5++;
  }

  /* Check results. */
  d = readdir(dirp);
  if (d != (struct dirent *) NULL) e(2);
  if (f1 != 1 || f3 != 1 || f5 != 1) e(3);
  if (f2 != 0 || f4 != 0) e(4);
  if (dot != 1 || dotdot != 1) e(5);
  subtest = subt;
  return;
}


void test20b()
{
/* Subtest 4.  Test error handling. */

  int fd;
  DIR *dirp;

  subtest = 4;

  if (opendir("foo/xyz/---") != DIR_NULL) e(1);
  if (errno != ENOENT) e(2);
  if (mkdir("foo", 0777) < 0) e(3);
  if (chmod("foo", 0) < 0) e(4);
  if (opendir("foo/xyz/--") != DIR_NULL) e(5);
  if (errno != EACCES) e(6);
  if (chmod("foo", 0777) != 0) e(7);
  if (rmdir("foo") != 0) e(8);
  if ((fd = creat("abc", 0666)) < 0) e(9);
  if (close(fd) < 0) e(10);
  if (opendir("abc/xyz") != DIR_NULL) e(11);
  if (errno != ENOTDIR) e(12);
  if ((dirp = opendir(".")) == DIR_NULL) e(13);
  if (closedir(dirp) != 0) e(14);
  if (unlink("abc") != 0) e(15);

}


void test20c()
{
/* Subtest 5.  See what happens if we open too many directory streams. */

  int i, j;
  DIR *dirp[MAX_FD];

  subtest = 5;

  for (i = 0; i < MAX_FD; i++) {
	dirp[i] = opendir(".");
	if (dirp[i] == (DIR *) NULL) {
		/* We have hit the limit. */
		if (errno != EMFILE && errno != ENOMEM) e(1);
		for (j = 0; j < i; j++) {
			if (closedir(dirp[j]) != 0) e(2);	/* close */
		}
		return;
	}
  }

  /* Control should never come here.  This is an error. */
  e(3);
  for (i = 0; i < MAX_FD; i++) closedir(dirp[i]);	/* don't check */
}

void test20d()
{
/* Test chdir and getcwd(). */

  int fd;
  char *s;
  char base[BUF_SIZE], buf2[BUF_SIZE], tmp[BUF_SIZE];

  subtest = 6;

  if (getcwd(base, BUF_SIZE) == (char *) NULL) e(1); /* get test dir's path */
  if (system("rm -rf Dir") != 0) e(2);	/* remove residue of previous test */
  if (mkdir("Dir", 0777) < 0) e(3); 	/* create directory called "Dir" */

  /* Change to Dir and verify that it worked. */
  if (chdir("Dir") < 0) e(4);	/* go to Dir */
  s = getcwd(buf2, BUF_SIZE);	/* get full path of Dir */
  if (s == (char *) NULL) e(5);	/* check for error return */
  if (s != buf2) e(6);		/* if successful, first arg is returned */
  strcpy(tmp, base);		/* concatenate base name and "/Dir" */
  strcat(tmp, "/");
  strcat(tmp, "Dir");
  if (strcmp(tmp, s) != 0) e(7);

  /* Change to ".." and verify that it worked. */
  if (chdir("..") < 0) e(8);
  if (getcwd(buf2, BUF_SIZE) != buf2) e(9);
  if (strcmp(buf2, base) != 0) e(10);

  /* Now make calls that do nothing, but do it in a strange way. */
  if (chdir("Dir/..") < 0) e(11);
  if (getcwd(buf2, BUF_SIZE) != buf2) e(12);
  if (strcmp(buf2, base) != 0) e(13);

  if (chdir("Dir/../Dir/..") < 0) e(14);
  if (getcwd(buf2, BUF_SIZE) != buf2) e(15);
  if (strcmp(buf2, base) != 0) e(16);

  if (chdir("Dir/../Dir/../Dir/../Dir/../Dir/../Dir/../Dir/..") < 0) e(17);
  if (getcwd(buf2, BUF_SIZE) != buf2) e(18);
  if (strcmp(buf2, base) != 0) e(19);

  /* Make Dir unreadable and unsearchable.  Check error message. */
  if (chmod("Dir", 0) < 0) e(20);
  if (chdir("Dir") >= 0) e(21);
  if (errno != EACCES) e(22);

  /* Check error message for bad path. */
  if (chmod("Dir", 0777) < 0) e(23);
  if (chdir("Dir/x/y") != ERR_CODE) e(24);
  if (errno != ENOENT) e(25);

  if ( (fd=creat("Dir/x", 0777)) < 0) e(26);
  if (close(fd) != 0) e(27);
  if (chdir("Dir/x/y") != ERR_CODE) e(28);
  if (errno != ENOTDIR) e(29);  

  /* Check empty string. */
  if (chdir("") != ERR_CODE) e(30);
  if (errno != ENOENT) e(31);

  /* Remove the directory. */
  if (unlink("Dir/x") != 0) e(32);
  if (system("rmdir Dir") != 0) e(33);
}


void test20e()
{
/* Test open. */

  int fd, bytes, bytes2;
  char buf[RD_BUF];

  subtest = 7;

  unlink("T20");		/* get rid of it in case it exists */

  /* Create a test file. */
  bytes = strlen(str);
  bytes2 = strlen(str2);
  if ((fd = creat("T20", 0777)) < 0) e(1);
  if (write(fd, str, bytes) != bytes) e(2);	/* T20 now has 'bytes' bytes */
  if (close(fd) != 0) e(3);

  /* Test opening a file with O_RDONLY. */
  if ((fd = open("T20", O_RDONLY)) < 0) e(4);
  buf[0] = '\0';
  if (read(fd, buf, RD_BUF) != bytes) e(5);
  if (strncmp(buf, str, bytes) != 0) e(6);
  if (close(fd) < 0) e(7);

  /* Test the same thing, only with O_RDWR now. */
  if ((fd = open("T20", O_RDWR)) < 0) e(8);
  buf[0] = '\0';
  if (read(fd, buf, RD_BUF) != bytes) e(9);
  if (strncmp(buf, str, bytes) != 0) e(10);
  if (close(fd) < 0) e(11);

  /* Try opening and reading with O_WRONLY.  It should fail. */
  if ((fd = open("T20", O_WRONLY)) < 0) e(12);
  buf[0] = '\0';
  if (read(fd, buf, RD_BUF) >= 0) e(13);
  if (close(fd) != 0) e(14);

  /* Test O_APPEND. */
  if ((fd = open("T20", O_RDWR | O_APPEND)) < 0) e(15);
  if (lseek(fd, 0L, SEEK_SET) < 0) e(16);	/* go to start of file */
  if ( write(fd, str2, bytes2) != bytes2) e(17); /* write at start of file */
  if (lseek(fd, 0L, SEEK_SET) < 0) e(18); 	/* go back to start again */
  if (read(fd, buf, RD_BUF) != bytes + bytes2) e(19); /* read whole file */
  if (strncmp(buf, str, bytes) != 0) e(20);
  if (close(fd) != 0) e(21);

  /* Get rid of the file. */
  if (unlink("T20") < 0) e(22);
}

void test20f()
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -