Module Name:    src
Committed By:   kamil
Date:           Tue Feb  5 17:30:19 UTC 2019

Modified Files:
        src/tests/lib/libc/stdio: t_fopen.c

Log Message:
Add 2 new tests in t_fopen

Added:
 - fopen_nullptr (without COMPAT_10)
 - fopen_nullptr_compat10 (with COMPAT_10)

PR kern/53948

Reviewed by <mgorny>


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/tests/lib/libc/stdio/t_fopen.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/lib/libc/stdio/t_fopen.c
diff -u src/tests/lib/libc/stdio/t_fopen.c:1.5 src/tests/lib/libc/stdio/t_fopen.c:1.6
--- src/tests/lib/libc/stdio/t_fopen.c:1.5	Mon Nov  6 23:06:55 2017
+++ src/tests/lib/libc/stdio/t_fopen.c	Tue Feb  5 17:30:19 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_fopen.c,v 1.5 2017/11/06 23:06:55 kre Exp $ */
+/*	$NetBSD: t_fopen.c,v 1.6 2019/02/05 17:30:19 kamil Exp $ */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -29,14 +29,18 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_fopen.c,v 1.5 2017/11/06 23:06:55 kre Exp $");
+__RCSID("$NetBSD: t_fopen.c,v 1.6 2019/02/05 17:30:19 kamil Exp $");
 
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/module.h>
 #include <atf-c.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <paths.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -287,6 +291,114 @@ ATF_TC_CLEANUP(fopen_mode, tc)
 	(void)unlink(path);
 }
 
+static void
+check_kernel_modular(void)
+{
+	int err;
+
+	err = modctl(MODCTL_EXISTS, 0);
+	if (err == 0) return;
+	if (errno == ENOSYS)
+		atf_tc_skip("Kernel does not have 'options MODULAR'.");
+	if (errno == EPERM)
+		return; /* Module loading can be administratively forbidden */
+	ATF_REQUIRE_EQ_MSG(errno, 0, "unexpected error %d from "
+	    "modctl(MODCTL_EXISTS, 0)", errno);
+}
+
+static bool
+is_module_present(const char *name)
+{
+	bool found;
+	size_t len;
+	int count;
+	struct iovec iov;
+	modstat_t *ms;
+
+	for (len = 8192; ;) {
+		iov.iov_base = malloc(len);
+		iov.iov_len = len;
+
+		errno = 0;
+
+		if (modctl(MODCTL_STAT, &iov) != 0) {
+			fprintf(stderr, "modctl(MODCTL_STAT) failed: %s\n",
+			    strerror(errno));
+			atf_tc_fail("Failed to query module status");
+		}
+		if (len >= iov.iov_len)
+			break;
+		free(iov.iov_base);
+		len = iov.iov_len;
+	}
+
+	found = false;
+	count = *(int *)iov.iov_base;
+	ms = (modstat_t *)((char *)iov.iov_base + sizeof(int));
+	while (count > 0) {
+		if (strcmp(ms->ms_name, name) == 0) {
+			found = true;
+			break;
+		}
+		ms++;
+		count--;
+	}
+
+	free(iov.iov_base);
+
+	return found;
+}
+
+#define COMPAT10_MODNAME "compat_10"
+
+ATF_TC(fopen_nullptr);
+ATF_TC_HEAD(fopen_nullptr, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test fopen(3) with NULL path (without "
+	    COMPAT10_MODNAME ")");
+}
+
+ATF_TC_BODY(fopen_nullptr, tc)
+{
+	bool compat10;
+
+	check_kernel_modular();
+	compat10 = is_module_present(COMPAT10_MODNAME);
+
+	if (compat10)
+		atf_tc_skip("Kernel does have the " COMPAT10_MODNAME
+		    " module loaded into the kernel");
+
+	/* NULL shall trigger error */
+	ATF_REQUIRE_ERRNO(EFAULT, fopen(NULL, "r") == NULL);
+}
+
+ATF_TC(fopen_nullptr_compat10);
+ATF_TC_HEAD(fopen_nullptr_compat10, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test fopen(3) with NULL path (with "
+	    COMPAT10_MODNAME ")");
+}
+
+ATF_TC_BODY(fopen_nullptr_compat10, tc)
+{
+	FILE *fp;
+	bool compat10;
+
+	check_kernel_modular();
+	compat10 = is_module_present(COMPAT10_MODNAME);
+
+	if (!compat10)
+		atf_tc_skip("Kernel does not have the " COMPAT10_MODNAME
+		    " module loaded into the kernel");
+
+	/* NULL is translated to "." and shall success */
+	fp = fopen(NULL, "r");
+
+	ATF_REQUIRE(fp != NULL);
+	ATF_REQUIRE(fclose(fp) == 0);
+}
+
 ATF_TC(fopen_perm);
 ATF_TC_HEAD(fopen_perm, tc)
 {
@@ -482,6 +594,8 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, fopen_append);
 	ATF_TP_ADD_TC(tp, fopen_err);
 	ATF_TP_ADD_TC(tp, fopen_mode);
+	ATF_TP_ADD_TC(tp, fopen_nullptr);
+	ATF_TP_ADD_TC(tp, fopen_nullptr_compat10);
 	ATF_TP_ADD_TC(tp, fopen_perm);
 	ATF_TP_ADD_TC(tp, fopen_regular);
 	ATF_TP_ADD_TC(tp, fopen_symlink);

Reply via email to