Module Name:    src
Committed By:   kamil
Date:           Thu Jun 20 03:31:54 UTC 2019

Modified Files:
        src/lib/libc/sys: mknod.2
        src/sys/compat/netbsd32: netbsd32_netbsd.c
        src/sys/kern: vfs_syscalls.c
        src/sys/sys: vfs_syscalls.h
        src/tests/lib/libc/c063: t_mkfifoat.c
        src/tests/lib/libc/sys: t_mkfifo.c

Log Message:
Add mkfifo{,at}(2) mode in mknod{,at}(2) as requested by POSIX

mknod with mode & S_IFIFO and dev=0 shall behave like mkfifo.

Update the documentation to reflect this state.

Add ATF tests.

This is an in-kernel implementation as typically user-space programs use
mkfifo(2) directly, however whenever there is need to bypass libc (like in
valgrind) then portable POSIX software calls the mknod syscall.

Noted on tech-kern@ by Greg Troxel.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 src/lib/libc/sys/mknod.2
cvs rdiff -u -r1.227 -r1.228 src/sys/compat/netbsd32/netbsd32_netbsd.c
cvs rdiff -u -r1.530 -r1.531 src/sys/kern/vfs_syscalls.c
cvs rdiff -u -r1.24 -r1.25 src/sys/sys/vfs_syscalls.h
cvs rdiff -u -r1.4 -r1.5 src/tests/lib/libc/c063/t_mkfifoat.c
cvs rdiff -u -r1.2 -r1.3 src/tests/lib/libc/sys/t_mkfifo.c

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

Modified files:

Index: src/lib/libc/sys/mknod.2
diff -u src/lib/libc/sys/mknod.2:1.29 src/lib/libc/sys/mknod.2:1.30
--- src/lib/libc/sys/mknod.2:1.29	Mon Nov 20 17:03:31 2017
+++ src/lib/libc/sys/mknod.2	Thu Jun 20 03:31:54 2019
@@ -1,4 +1,4 @@
-.\"	$NetBSD: mknod.2,v 1.29 2017/11/20 17:03:31 uwe Exp $
+.\"	$NetBSD: mknod.2,v 1.30 2019/06/20 03:31:54 kamil Exp $
 .\"
 .\" Copyright (c) 1980, 1991, 1993
 .\"	The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)mknod.2	8.1 (Berkeley) 6/4/93
 .\"
-.Dd July 29, 2013
+.Dd June 20, 2019
 .Dt MKNOD 2
 .Os
 .Sh NAME
@@ -47,7 +47,28 @@
 .Ft int
 .Fn mknodat "int fd" "const char *path" "mode_t mode" "dev_t dev"
 .Sh DESCRIPTION
-The device special file
+.Nm
+with
+.Dv S_IFIFO
+specified in
+.Fa mode
+and 0 in
+.Fa dev
+makes a fifo file.
+This call is respectively a portable alias for
+.Xr mkfifo 2
+and
+.Xr mkfifoat 2 .
+.Pp
+.Nm
+with
+.Dv S_IFCHR
+or
+.Dv S_IFBLK
+in
+.Fa mode
+makes a device special file.
+The file
 .Fa path
 is created with the major and minor
 device numbers specified by
@@ -87,7 +108,7 @@ can be set to
 in order to specify the current directory.
 .Pp
 .Fn mknod
-requires super-user privileges.
+requires super-user privileges for creating device special files.
 .Sh RETURN VALUES
 .Rv -std mknod mknodat
 .Sh ERRORS
@@ -138,6 +159,8 @@ node is being created.
 A component of the path prefix is not a directory.
 .It Bq Er EPERM
 The process's effective user ID is not super-user.
+.It Bq Er EOPNOTSUPP
+The kernel has not been configured to support fifo's.
 .It Bq Er EROFS
 The named file resides on a read-only file system.
 .El
@@ -178,3 +201,10 @@ A
 .Fn mknod
 function call appeared in
 .At v6 .
+.Pp
+The alias mode for
+.Xr mkfifo 2
+and
+.Xr mkfifoat 2
+first appeared in
+.Nx 9 .

Index: src/sys/compat/netbsd32/netbsd32_netbsd.c
diff -u src/sys/compat/netbsd32/netbsd32_netbsd.c:1.227 src/sys/compat/netbsd32/netbsd32_netbsd.c:1.228
--- src/sys/compat/netbsd32/netbsd32_netbsd.c:1.227	Tue Jun 18 22:34:25 2019
+++ src/sys/compat/netbsd32/netbsd32_netbsd.c	Thu Jun 20 03:31:54 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: netbsd32_netbsd.c,v 1.227 2019/06/18 22:34:25 kamil Exp $	*/
+/*	$NetBSD: netbsd32_netbsd.c,v 1.228 2019/06/20 03:31:54 kamil Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001, 2008, 2018 Matthew R. Green
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.227 2019/06/18 22:34:25 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: netbsd32_netbsd.c,v 1.228 2019/06/20 03:31:54 kamil Exp $");
 
 /*
  * below are all the standard NetBSD system calls, in the 32bit
@@ -297,8 +297,8 @@ netbsd32___mknod50(struct lwp *l, const 
 		syscallarg(netbsd32_dev_t) dev;
 	} */
 
-	return do_sys_mknod(l, SCARG_P32(uap, path), SCARG(uap, mode),
-	    SCARG(uap, dev), UIO_USERSPACE);
+	return do_posix_mknodat(l, AT_FDCWD, SCARG_P32(uap, path),
+	    SCARG(uap, mode), SCARG(uap, dev));
 }
 
 int

Index: src/sys/kern/vfs_syscalls.c
diff -u src/sys/kern/vfs_syscalls.c:1.530 src/sys/kern/vfs_syscalls.c:1.531
--- src/sys/kern/vfs_syscalls.c:1.530	Wed Jun 19 14:16:06 2019
+++ src/sys/kern/vfs_syscalls.c	Thu Jun 20 03:31:54 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_syscalls.c,v 1.530 2019/06/19 14:16:06 kamil Exp $	*/
+/*	$NetBSD: vfs_syscalls.c,v 1.531 2019/06/20 03:31:54 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.530 2019/06/19 14:16:06 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.531 2019/06/20 03:31:54 kamil Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_fileassoc.h"
@@ -2151,6 +2151,20 @@ sys___fhstatvfs140(struct lwp *l, const 
 	return error;
 }
 
+int
+do_posix_mknodat(struct lwp *l, int fdat, const char *pathname, mode_t mode,
+    dev_t dev)
+{
+
+	if ((mode & S_IFIFO) && dev == 0)
+		return do_sys_mkfifoat(l, fdat, pathname, mode);
+	else if (mode & (S_IFCHR | S_IFBLK))
+		return do_sys_mknodat(l, fdat, pathname, mode, dev,
+		    UIO_USERSPACE);
+	else
+		return EINVAL;
+}
+
 /*
  * Create a special file.
  */
@@ -2164,8 +2178,8 @@ sys___mknod50(struct lwp *l, const struc
 		syscallarg(mode_t) mode;
 		syscallarg(dev_t) dev;
 	} */
-	return do_sys_mknodat(l, AT_FDCWD, SCARG(uap, path),
-	    SCARG(uap, mode), SCARG(uap, dev), UIO_USERSPACE);
+	return do_posix_mknodat(l, AT_FDCWD, SCARG(uap, path),
+	    SCARG(uap, mode), SCARG(uap, dev));
 }
 
 int
@@ -2180,8 +2194,8 @@ sys_mknodat(struct lwp *l, const struct 
 		syscallarg(dev_t) dev;
 	} */
 
-	return do_sys_mknodat(l, SCARG(uap, fd), SCARG(uap, path),
-	    SCARG(uap, mode), SCARG(uap, dev), UIO_USERSPACE);
+	return do_posix_mknodat(l, SCARG(uap, fd), SCARG(uap, path),
+	    SCARG(uap, mode), SCARG(uap, dev));
 }
 
 int

Index: src/sys/sys/vfs_syscalls.h
diff -u src/sys/sys/vfs_syscalls.h:1.24 src/sys/sys/vfs_syscalls.h:1.25
--- src/sys/sys/vfs_syscalls.h:1.24	Tue Jun 18 22:34:26 2019
+++ src/sys/sys/vfs_syscalls.h	Thu Jun 20 03:31:54 2019
@@ -1,4 +1,4 @@
-/*     $NetBSD: vfs_syscalls.h,v 1.24 2019/06/18 22:34:26 kamil Exp $        */
+/*     $NetBSD: vfs_syscalls.h,v 1.25 2019/06/20 03:31:54 kamil Exp $        */
 
 /*
  * Copyright (c) 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -70,6 +70,7 @@ int dofhopen(struct lwp *, const void *,
 int	do_sys_linkat(struct lwp *, int, const char *, int, const char *, int, register_t *);
 int	do_sys_unlink(const char *, enum uio_seg);
 int	do_sys_rename(const char *, const char *, enum uio_seg, int);
+int	do_posix_mknodat(struct lwp *, int, const char *, mode_t, dev_t);
 int	do_sys_mknod(struct lwp *, const char *, mode_t, dev_t, enum uio_seg);
 int	do_sys_mknodat(struct lwp *, int, const char *, mode_t, dev_t, enum uio_seg);
 int	do_sys_chmodat(struct lwp *, int, const char *, int, int);

Index: src/tests/lib/libc/c063/t_mkfifoat.c
diff -u src/tests/lib/libc/c063/t_mkfifoat.c:1.4 src/tests/lib/libc/c063/t_mkfifoat.c:1.5
--- src/tests/lib/libc/c063/t_mkfifoat.c:1.4	Sat Jan 14 20:55:26 2017
+++ src/tests/lib/libc/c063/t_mkfifoat.c	Thu Jun 20 03:31:53 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_mkfifoat.c,v 1.4 2017/01/14 20:55:26 christos Exp $ */
+/*	$NetBSD: t_mkfifoat.c,v 1.5 2019/06/20 03:31:53 kamil Exp $ */
 
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_mkfifoat.c,v 1.4 2017/01/14 20:55:26 christos Exp $");
+__RCSID("$NetBSD: t_mkfifoat.c,v 1.5 2019/06/20 03:31:53 kamil Exp $");
 
 #include <atf-c.h>
 #include <errno.h>
@@ -108,6 +108,32 @@ ATF_TC_BODY(mkfifoat_fderr, tc)
 	ATF_REQUIRE(mkfifoat(-1, FIFO, mode) == -1);
 }
 
+ATF_TC(mknodat_s_ififo);
+ATF_TC_HEAD(mknodat_s_ififo, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test mknodat(2) with S_IFIFO");
+}
+
+ATF_TC_BODY(mknodat_s_ififo, tc)
+{
+	struct stat st;
+	int dfd;
+	mode_t mode = S_IFIFO | 0600;
+
+	(void)memset(&st, 0, sizeof(struct stat));
+
+	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
+	ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
+	ATF_REQUIRE(mknodat(dfd, BASEFIFO, mode, 0) != -1);
+	ATF_REQUIRE(access(FIFO, F_OK) == 0);
+	ATF_REQUIRE(stat(FIFO, &st) == 0);
+
+	if (S_ISFIFO(st.st_mode) == 0)
+		atf_tc_fail("invalid mode from mknodat(2) with S_IFIFO");
+
+	(void)close(dfd);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 
@@ -115,6 +141,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, mkfifoat_fdcwd);
 	ATF_TP_ADD_TC(tp, mkfifoat_fdcwderr);
 	ATF_TP_ADD_TC(tp, mkfifoat_fderr);
+	ATF_TP_ADD_TC(tp, mknodat_s_ififo);
 
 	return atf_no_error();
 }

Index: src/tests/lib/libc/sys/t_mkfifo.c
diff -u src/tests/lib/libc/sys/t_mkfifo.c:1.2 src/tests/lib/libc/sys/t_mkfifo.c:1.3
--- src/tests/lib/libc/sys/t_mkfifo.c:1.2	Wed Nov  2 06:04:48 2011
+++ src/tests/lib/libc/sys/t_mkfifo.c	Thu Jun 20 03:31:54 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $ */
+/* $NetBSD: t_mkfifo.c,v 1.3 2019/06/20 03:31:54 kamil Exp $ */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: t_mkfifo.c,v 1.2 2011/11/02 06:04:48 jruoho Exp $");
+__RCSID("$NetBSD: t_mkfifo.c,v 1.3 2019/06/20 03:31:54 kamil Exp $");
 
 #include <sys/stat.h>
 #include <sys/wait.h>
@@ -263,6 +263,34 @@ ATF_TC_CLEANUP(mkfifo_stat, tc)
 	(void)unlink(path);
 }
 
+ATF_TC_WITH_CLEANUP(mknod_s_ififo);
+ATF_TC_HEAD(mknod_s_ififo, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Test mknod(2) with S_IFIFO");
+}
+
+ATF_TC_BODY(mknod_s_ififo, tc)
+{
+	struct stat st;
+
+	support();
+
+	(void)memset(&st, 0, sizeof(struct stat));
+
+	ATF_REQUIRE(mknod(path, S_IFIFO | 0600, 0) == 0);
+	ATF_REQUIRE(stat(path, &st) == 0);
+
+	if (S_ISFIFO(st.st_mode) == 0)
+		atf_tc_fail("invalid mode from mknod(2) with S_IFIFO");
+
+	ATF_REQUIRE(unlink(path) == 0);
+}
+
+ATF_TC_CLEANUP(mknod_s_ififo, tc)
+{
+	(void)unlink(path);
+}
+
 ATF_TP_ADD_TCS(tp)
 {
 
@@ -271,6 +299,7 @@ ATF_TP_ADD_TCS(tp)
 	ATF_TP_ADD_TC(tp, mkfifo_nonblock);
 	ATF_TP_ADD_TC(tp, mkfifo_perm);
 	ATF_TP_ADD_TC(tp, mkfifo_stat);
+	ATF_TP_ADD_TC(tp, mknod_s_ififo);
 
 	return atf_no_error();
 }

Reply via email to