Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/tests/lib/libc/sys Add some cases for dup2(2) and dup3(2).
details: https://anonhg.NetBSD.org/src/rev/cd227b3532af
branches: trunk
changeset: 767316:cd227b3532af
user: jruoho <jruoho%NetBSD.org@localhost>
date: Fri Jul 15 09:40:16 2011 +0000
description:
Add some cases for dup2(2) and dup3(2).
diffstat:
tests/lib/libc/sys/t_dup.c | 240 ++++++++++++++++++++++++++++++++++++--------
1 files changed, 197 insertions(+), 43 deletions(-)
diffs (truncated from 306 to 300 lines):
diff -r 4fdee0dcc999 -r cd227b3532af tests/lib/libc/sys/t_dup.c
--- a/tests/lib/libc/sys/t_dup.c Fri Jul 15 08:17:36 2011 +0000
+++ b/tests/lib/libc/sys/t_dup.c Fri Jul 15 09:40:16 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_dup.c,v 1.2 2011/07/07 10:27:31 jruoho Exp $ */
+/* $NetBSD: t_dup.c,v 1.3 2011/07/15 09:40:16 jruoho Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: t_dup.c,v 1.2 2011/07/07 10:27:31 jruoho Exp $");
+__RCSID("$NetBSD: t_dup.c,v 1.3 2011/07/15 09:40:16 jruoho Exp $");
#include <sys/resource.h>
#include <sys/stat.h>
@@ -38,13 +38,191 @@
#include <atf-c.h>
#include <errno.h>
#include <fcntl.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sysexits.h>
-static char path[] = "dup";
+static char path[] = "dup";
+static void check_mode(bool, bool, bool);
+
+static void
+check_mode(bool _dup, bool _dup2, bool _dup3)
+{
+ int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR };
+ int perm[5] = { 0700, 0400, 0600, 0444, 0666 };
+ struct stat st, st1;
+ int fd, fd1, fd2;
+ size_t i, j;
+
+ /*
+ * Check that a duplicated descriptor
+ * retains the mode of the original file.
+ */
+ for (i = 0; i < __arraycount(mode); i++) {
+
+ for (j = 0; j < __arraycount(perm); j++) {
+
+ fd1 = open(path, mode[i] | O_CREAT, perm[j]);
+ fd2 = open("/etc/passwd", O_RDONLY);
+
+ ATF_REQUIRE(fd1 >= 0);
+ ATF_REQUIRE(fd2 >= 0);
+
+ if (_dup != false)
+ fd = dup(fd1);
+ else if (_dup2 != false)
+ fd = dup2(fd1, fd2);
+ else if (_dup3 != false)
+ fd = dup3(fd1, fd2, O_CLOEXEC);
+ else {
+ fd = -1;
+ }
+
+ ATF_REQUIRE(fd >= 0);
+
+ (void)memset(&st, 0, sizeof(struct stat));
+ (void)memset(&st1, 0, sizeof(struct stat));
+
+ ATF_REQUIRE(fstat(fd, &st) == 0);
+ ATF_REQUIRE(fstat(fd1, &st1) == 0);
+
+ if (st.st_mode != st1.st_mode)
+ atf_tc_fail("invalid mode");
+
+ (void)close(fd);
+ (void)close(fd1);
+ (void)close(fd2);
+ (void)unlink(path);
+ }
+ }
+}
+
+ATF_TC(dup2_basic);
+ATF_TC_HEAD(dup2_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_basic, tc)
+{
+ int fd, fd1, fd2;
+
+ fd1 = open("/etc/passwd", O_RDONLY);
+ fd2 = open("/etc/passwd", O_RDONLY);
+
+ ATF_REQUIRE(fd1 >= 0);
+ ATF_REQUIRE(fd2 >= 0);
+
+ fd = dup2(fd1, fd2);
+ ATF_REQUIRE(fd >= 0);
+
+ if (fd != fd2)
+ atf_tc_fail("invalid descriptor");
+
+ (void)close(fd);
+ (void)close(fd1);
+
+ ATF_REQUIRE(close(fd2) != 0);
+}
+
+ATF_TC(dup2_err);
+ATF_TC_HEAD(dup2_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_err, tc)
+{
+ int fd;
+
+ fd = open("/etc/passwd", O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(-1, -1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(fd, -1) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup2(-1, fd) == -1);
+
+ /*
+ * Note that this should not fail with EINVAL.
+ */
+ ATF_REQUIRE(dup2(fd, fd) != -1);
+
+ (void)close(fd);
+}
+
+ATF_TC_WITH_CLEANUP(dup2_mode);
+ATF_TC_HEAD(dup2_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup2(2)");
+}
+
+ATF_TC_BODY(dup2_mode, tc)
+{
+ check_mode(false, true, false);
+}
+
+ATF_TC_CLEANUP(dup2_mode, tc)
+{
+ (void)unlink(path);
+}
+
+
+ATF_TC(dup3_err);
+ATF_TC_HEAD(dup3_err, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test error conditions of dup3(2)");
+}
+
+ATF_TC_BODY(dup3_err, tc)
+{
+ int fd;
+
+ atf_tc_expect_fail("PR lib/45148");
+
+ fd = open("/etc/passwd", O_RDONLY);
+ ATF_REQUIRE(fd >= 0);
+
+ errno = 0;
+ ATF_REQUIRE(dup3(fd, fd, O_CLOEXEC) != -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(-1, -1, O_CLOEXEC) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(fd, -1, O_CLOEXEC) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup3(-1, fd, O_CLOEXEC) == -1);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EINVAL, dup3(fd, 1, O_NOFOLLOW) == -1); /* Fails. */
+
+ (void)close(fd);
+}
+
+ATF_TC_WITH_CLEANUP(dup3_mode);
+ATF_TC_HEAD(dup3_mode, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of dup3(2)");
+}
+
+ATF_TC_BODY(dup3_mode, tc)
+{
+ check_mode(false, false, true);
+}
+
+ATF_TC_CLEANUP(dup3_mode, tc)
+{
+ (void)unlink(path);
+}
ATF_TC(dup_err);
ATF_TC_HEAD(dup_err, tc)
@@ -54,7 +232,9 @@
ATF_TC_BODY(dup_err, tc)
{
- ATF_REQUIRE(dup(-1) != 0);
+
+ errno = 0;
+ ATF_REQUIRE_ERRNO(EBADF, dup(-1) == -1);
}
ATF_TC_WITH_CLEANUP(dup_max);
@@ -78,8 +258,8 @@
/*
* Open a temporary file until the
* maximum number of open files is
- * reached. Ater that dup(2) should
- * fail with EMFILE.
+ * reached. Ater that dup(2) family
+ * should fail with EMFILE.
*/
(void)closefrom(0);
(void)memset(&res, 0, sizeof(struct rlimit));
@@ -123,11 +303,15 @@
if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) {
if (WEXITSTATUS(sta) == EX_OSERR)
- atf_tc_fail("unknown error");
+ atf_tc_fail("system call error");
if (WEXITSTATUS(sta) == EX_DATAERR)
atf_tc_fail("dup(2) dupped more than RLIMIT_NOFILE");
+
+ atf_tc_fail("unknown error");
}
+
+ (void)unlink(path);
}
ATF_TC_CLEANUP(dup_max, tc)
@@ -143,42 +327,7 @@
ATF_TC_BODY(dup_mode, tc)
{
- int mode[3] = { O_RDONLY, O_WRONLY, O_RDWR };
- int perm[5] = { 0700, 0400, 0600, 0444, 0666 };
- struct stat st1, st2;
- int fd1, fd2;
- size_t i, j;
-
- /*
- * Check that a duplicated descriptor
- * retains the mode of the original file.
- */
- for (i = 0; i < __arraycount(mode); i++) {
-
- for (j = 0; j < __arraycount(perm); j++) {
-
- fd1 = open(path, mode[i] | O_CREAT, perm[j]);
-
- if (fd1 < 0)
- return;
-
- fd2 = dup(fd1);
- ATF_REQUIRE(fd2 >= 0);
-
- (void)memset(&st1, 0, sizeof(struct stat));
- (void)memset(&st2, 0, sizeof(struct stat));
-
- ATF_REQUIRE(fstat(fd1, &st1) == 0);
- ATF_REQUIRE(fstat(fd2, &st2) == 0);
-
- if (st1.st_mode != st2.st_mode)
- atf_tc_fail("invalid mode");
-
- ATF_REQUIRE(close(fd1) == 0);
- ATF_REQUIRE(close(fd2) == 0);
- ATF_REQUIRE(unlink(path) == 0);
- }
- }
+ check_mode(true, false, false);
}
ATF_TC_CLEANUP(dup_mode, tc)
@@ -189,6 +338,11 @@
ATF_TP_ADD_TCS(tp)
{
+ ATF_TP_ADD_TC(tp, dup2_basic);
+ ATF_TP_ADD_TC(tp, dup2_err);
Home |
Main Index |
Thread Index |
Old Index