ATF_TC_BODY(rfork, tc)
{
	struct stat sb;
	struct lwp *l, *l2;
	int fd;

	RZ(rump_init());

	ATF_REQUIRE_EQ(rump_pub_lwproc_rfork(RUMP_RFFDG|RUMP_RFCFDG), EINVAL);

	RZ(rump_pub_lwproc_rfork(0));
	l = rump_pub_lwproc_curlwp();

	RL(fd = rump_sys_open("/file", O_RDWR | O_CREAT, 0777));

	/* ok, first check rfork(RUMP_RFCFDG) does *not* preserve fd's */
	RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
	ATF_REQUIRE_ERRNO(EBADF, rump_sys_write(fd, &fd, sizeof(fd)) == -1);

	/* then check that rfork(0) does */
	rump_pub_lwproc_switch(l);
	RZ(rump_pub_lwproc_rfork(0));
	ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd));
	RL(rump_sys_fstat(fd, &sb));
	l2 = rump_pub_lwproc_curlwp();

	/*
	 * check that the shared fd table is really shared by
	 * closing fd in parent
	 */
	rump_pub_lwproc_switch(l);
	RL(rump_sys_close(fd));
	rump_pub_lwproc_switch(l2);
	ATF_REQUIRE_ERRNO(EBADF, rump_sys_fstat(fd, &sb) == -1);

	/* redo, this time copying the fd table instead of sharing it */
	rump_pub_lwproc_releaselwp();
	rump_pub_lwproc_switch(l);
	RL(fd = rump_sys_open("/file", O_RDWR, 0777));
	RZ(rump_pub_lwproc_rfork(RUMP_RFFDG));
	ATF_REQUIRE_EQ(rump_sys_write(fd, &fd, sizeof(fd)), sizeof(fd));
	RL(rump_sys_fstat(fd, &sb));
	l2 = rump_pub_lwproc_curlwp();

	/* check that the fd table is copied */
	rump_pub_lwproc_switch(l);
	RL(rump_sys_close(fd));
	rump_pub_lwproc_switch(l2);
	RL(rump_sys_fstat(fd, &sb));
	ATF_REQUIRE_EQ(sb.st_size, sizeof(fd));
}
static void
extendbody(const atf_tc_t *tc, off_t seekcnt)
{
	char buf[TESTSZ+1];
	struct stat sb;
	int fd;

	FSTEST_ENTER();
	RL(fd = rump_sys_open("testfile",
	    O_CREAT | O_RDWR | (seekcnt ? O_APPEND : 0)));
	RL(rump_sys_ftruncate(fd, seekcnt));
	RL(rump_sys_fstat(fd, &sb));
	ATF_REQUIRE_EQ(sb.st_size, seekcnt);

	ATF_REQUIRE_EQ(rump_sys_write(fd, TESTSTR, TESTSZ), TESTSZ);
	ATF_REQUIRE_EQ(rump_sys_pread(fd, buf, TESTSZ, seekcnt), TESTSZ);
	ATF_REQUIRE_STREQ(buf, TESTSTR);

	RL(rump_sys_fstat(fd, &sb));
	ATF_REQUIRE_EQ(sb.st_size, (off_t)TESTSZ + seekcnt);
	RL(rump_sys_close(fd));
	FSTEST_EXIT();
}
示例#3
0
int
main(int argc, char *argv[])
{
	struct stat st;
	int ch, rc, errs, am_readlink;
	int lsF, fmtchar, usestat, fn, nonl, quiet;
	const char *statfmt, *options, *synopsis;

	am_readlink = 0;
	lsF = 0;
	fmtchar = '\0';
	usestat = 0;
	nonl = 0;
	quiet = 0;
	linkfail = 0;
	statfmt = NULL;
	timefmt = NULL;

	setprogname(argv[0]);

	if (strcmp(getprogname(), "readlink") == 0) {
		am_readlink = 1;
		options = "fnqsv";
		synopsis = "[-fnqsv] [file ...]";
		statfmt = "%Y";
		fmtchar = 'f';
		quiet = 1;
	} else {
		options = "f:FlLnqrst:x";
		synopsis = "[-FlLnqrsx] [-f format] [-t timefmt] [file ...]";
	}

	if (fsu_mount(&argc, &argv, MOUNT_READONLY) != 0)
		usage(synopsis);

	while ((ch = getopt(argc, argv, options)) != -1)
		switch (ch) {
		case 'F':
			lsF = 1;
			break;
		case 'L':
			usestat = 1;
			break;
		case 'n':
			nonl = 1;
			break;
		case 'q':
			quiet = 1;
			break;
		case 'f':
			if (am_readlink) {
				statfmt = "%R";
				break;
			}
			statfmt = optarg;
			/* FALLTHROUGH */
		case 'l':
		case 'r':
		case 's':
			if (am_readlink) {
				quiet = 1;
				break;
			}
			/*FALLTHROUGH*/
		case 'x':
			if (fmtchar != 0)
				errx(1, "can't use format '%c' with '%c'",
				    fmtchar, ch);
			fmtchar = ch;
			break;
		case 't':
			timefmt = optarg;
			break;
		case 'v':
			quiet = 0;
			break;
		default:
			usage(synopsis);
		}

	argc -= optind;
	argv += optind;
	fn = 1;

	if (fmtchar == '\0') {
		if (lsF)
			fmtchar = 'l';
		else {
			fmtchar = 'f';
			statfmt = DEF_FORMAT;
		}
	}

	if (lsF && fmtchar != 'l')
		errx(1, "can't use format '%c' with -F", fmtchar);

	switch (fmtchar) {
	case 'f':
		/* statfmt already set */
		break;
	case 'l':
		statfmt = lsF ? LSF_FORMAT : LS_FORMAT;
		break;
	case 'r':
		statfmt = RAW_FORMAT;
		break;
	case 's':
		statfmt = SHELL_FORMAT;
		if (timefmt == NULL)
			timefmt = "%s";
		break;
	case 'x':
		statfmt = LINUX_FORMAT;
		if (timefmt == NULL)
			timefmt = "%c";
		break;
	default:
		usage(synopsis);
		/*NOTREACHED*/
	}

	if (timefmt == NULL)
		timefmt = TIME_FORMAT;

	errs = 0;
	do {
		if (argc == 0)
			rc = rump_sys_fstat(STDIN_FILENO, &st);
		else if (usestat) {
			/*
			 * Try stat() and if it fails, fall back to
			 * lstat() just in case we're examining a
			 * broken symlink.
			 */
			if ((rc = rump_sys_stat(argv[0], &st)) == -1 &&
			    errno == ENOENT &&
			    (rc = rump_sys_lstat(argv[0], &st)) == -1)
				errno = ENOENT;
		}
		else
			rc = rump_sys_lstat(argv[0], &st);

		if (rc == -1) {
			errs = 1;
			linkfail = 1;
			if (!quiet)
				warn("%s: %s",
				    argc == 0 ? "(stdin)" : argv[0],
				    usestat ? "stat" : "lstat");
		}
		else
			output(&st, argv[0], statfmt, fn, nonl, quiet);

		argv++;
		argc--;
		fn++;
	} while (argc > 0);

	return (am_readlink ? linkfail : errs);
}