Module Name:    src
Committed By:   rmind
Date:           Thu Dec 19 19:11:50 UTC 2013

Modified Files:
        src/lib/libc/gen: sysconf.c
        src/lib/librt: Makefile
        src/sys/sys: mman.h unistd.h
        src/usr.bin/getconf: getconf.c
Added Files:
        src/lib/librt: shm.c

Log Message:
Add shm_open(3) and shm_unlink(3) to support POSIX shared memory objects.
They are implemented using tmpfs (mounted at /var/shm).

Discussed on tech-{kern,userlevel} (quite a while ago).


To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.36 src/lib/libc/gen/sysconf.c
cvs rdiff -u -r1.16 -r1.17 src/lib/librt/Makefile
cvs rdiff -u -r0 -r1.1 src/lib/librt/shm.c
cvs rdiff -u -r1.44 -r1.45 src/sys/sys/mman.h
cvs rdiff -u -r1.54 -r1.55 src/sys/sys/unistd.h
cvs rdiff -u -r1.34 -r1.35 src/usr.bin/getconf/getconf.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/gen/sysconf.c
diff -u src/lib/libc/gen/sysconf.c:1.35 src/lib/libc/gen/sysconf.c:1.36
--- src/lib/libc/gen/sysconf.c:1.35	Fri Nov  2 21:43:07 2012
+++ src/lib/libc/gen/sysconf.c	Thu Dec 19 19:11:50 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysconf.c,v 1.35 2012/11/02 21:43:07 christos Exp $	*/
+/*	$NetBSD: sysconf.c,v 1.36 2013/12/19 19:11:50 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)sysconf.c	8.2 (Berkeley) 3/20/94";
 #else
-__RCSID("$NetBSD: sysconf.c,v 1.35 2012/11/02 21:43:07 christos Exp $");
+__RCSID("$NetBSD: sysconf.c,v 1.36 2013/12/19 19:11:50 rmind Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -345,6 +345,8 @@ sysconf(int name)
 		return _PASSWORD_LEN;
 	case _SC_REGEXP:
 		return _POSIX_REGEXP;
+	case _SC_SHARED_MEMORY_OBJECTS:
+		return _POSIX_SHARED_MEMORY_OBJECTS;
 	case _SC_SHELL:
 		return _POSIX_SHELL;
 	case _SC_SPAWN:

Index: src/lib/librt/Makefile
diff -u src/lib/librt/Makefile:1.16 src/lib/librt/Makefile:1.17
--- src/lib/librt/Makefile:1.16	Wed Mar 21 05:37:43 2012
+++ src/lib/librt/Makefile	Thu Dec 19 19:11:50 2013
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.16 2012/03/21 05:37:43 matt Exp $
+#	$NetBSD: Makefile,v 1.17 2013/12/19 19:11:50 rmind Exp $
 #
 
 .include <bsd.own.mk>
@@ -6,8 +6,8 @@
 WARNS?=	5
 
 LIB=	rt
-SRCS=	sem.c
-SRCS+=	pset.c
+
+SRCS=	sem.c shm.c pset.c
 
 MAN+=	aio.3 aio_cancel.3 aio_error.3 aio_fsync.3 aio_read.3 aio_return.3 \
 	aio_suspend.3 aio_write.3 lio_listio.3 \

Index: src/sys/sys/mman.h
diff -u src/sys/sys/mman.h:1.44 src/sys/sys/mman.h:1.45
--- src/sys/sys/mman.h:1.44	Thu Jan  5 15:19:52 2012
+++ src/sys/sys/mman.h	Thu Dec 19 19:11:50 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: mman.h,v 1.44 2012/01/05 15:19:52 reinoud Exp $	*/
+/*	$NetBSD: mman.h,v 1.45 2013/12/19 19:11:50 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1993
@@ -185,6 +185,8 @@ int	minherit(void *, size_t, int);
 void *	mremap(void *, size_t, void *, size_t, int);
 #endif
 int	posix_madvise(void *, size_t, int);
+int	shm_open(const char *, int, mode_t);
+int	shm_unlink(const char *);
 __END_DECLS
 
 #endif /* !_KERNEL */

Index: src/sys/sys/unistd.h
diff -u src/sys/sys/unistd.h:1.54 src/sys/sys/unistd.h:1.55
--- src/sys/sys/unistd.h:1.54	Fri Nov  2 21:41:26 2012
+++ src/sys/sys/unistd.h	Thu Dec 19 19:11:50 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: unistd.h,v 1.54 2012/11/02 21:41:26 christos Exp $	*/
+/*	$NetBSD: unistd.h,v 1.55 2013/12/19 19:11:50 rmind Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -129,8 +129,8 @@
 #define	_POSIX_REGEXP			1
 					/* semaphores */
 #define	_POSIX_SEMAPHORES		0
-					/* shared memory */
-#undef	_POSIX_SHARED_MEMORY_OBJECTS
+					/* shared memory objects */
+#define	_POSIX_SHARED_MEMORY_OBJECTS	0
 					/* shell */
 #define	_POSIX_SHELL			1
 					/* spin locks */
@@ -303,8 +303,9 @@
 #define	_SC_2_PBS_MESSAGE		84
 #define	_SC_2_PBS_TRACK			85
 
-/* This is implemented */
+/* These are implemented */
 #define	_SC_SPAWN			86
+#define	_SC_SHARED_MEMORY_OBJECTS	87
 
 /* Extensions found in Solaris and Linux. */
 #define	_SC_PHYS_PAGES		121

Index: src/usr.bin/getconf/getconf.c
diff -u src/usr.bin/getconf/getconf.c:1.34 src/usr.bin/getconf/getconf.c:1.35
--- src/usr.bin/getconf/getconf.c:1.34	Wed Aug 27 08:56:49 2008
+++ src/usr.bin/getconf/getconf.c	Thu Dec 19 19:11:50 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: getconf.c,v 1.34 2008/08/27 08:56:49 christos Exp $	*/
+/*	$NetBSD: getconf.c,v 1.35 2013/12/19 19:11:50 rmind Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: getconf.c,v 1.34 2008/08/27 08:56:49 christos Exp $");
+__RCSID("$NetBSD: getconf.c,v 1.35 2013/12/19 19:11:50 rmind Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -147,6 +147,7 @@ static const struct conf_variable conf_t
   { "_POSIX_MONOTONIC_CLOCK",	SYSCONF,	_SC_MONOTONIC_CLOCK	},
   { "_POSIX_PRIORITY_SCHEDULING", SYSCONF,	_SC_PRIORITY_SCHEDULING },
   { "_POSIX_SEMAPHORES",	SYSCONF,	_SC_SEMAPHORES		},
+  { "_POSIX_SHARED_MEMORY_OBJECTS", SYSCONF,	_SC_SHARED_MEMORY_OBJECTS },
   { "_POSIX_SYNCHRONIZED_IO",	SYSCONF,	_SC_SYNCHRONIZED_IO	},
   { "_POSIX_TIMERS",		SYSCONF,	_SC_TIMERS		},
 

Added files:

Index: src/lib/librt/shm.c
diff -u /dev/null src/lib/librt/shm.c:1.1
--- /dev/null	Thu Dec 19 19:11:50 2013
+++ src/lib/librt/shm.c	Thu Dec 19 19:11:50 2013
@@ -0,0 +1,136 @@
+/*	$NetBSD: shm.c,v 1.1 2013/12/19 19:11:50 rmind Exp $	*/
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Interface for POSIX shared memory objects.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: shm.c,v 1.1 2013/12/19 19:11:50 rmind Exp $");
+
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+
+/*
+ * Shared memory objects are supported using tmpfs.
+ */
+#define	SHMFS_DIR_PATH		"/var/shm"
+#define	SHMFS_DIR_MODE		(S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
+#define	SHMFS_OBJ_PREFIX	".shmobj_"
+
+#define	MOUNT_SHMFS		MOUNT_TMPFS
+
+static const char *		_shmfs_path = NULL;
+
+static bool
+_shm_check_fs(void)
+{
+	const char *shmfs = SHMFS_DIR_PATH;
+	struct statvfs sv;
+	struct stat st;
+
+	if (statvfs1(shmfs, &sv, ST_NOWAIT) == -1) {
+		return false;
+	}
+	if (strncmp(sv.f_fstypename, MOUNT_SHMFS, sizeof(sv.f_fstypename))) {
+		return false;
+	}
+
+	if (lstat(shmfs, &st) == -1) {
+		return false;
+	}
+	if ((st.st_mode & SHMFS_DIR_MODE) != SHMFS_DIR_MODE) {
+		return false;
+	}
+
+	_shmfs_path = shmfs;
+	return true;
+}
+
+static bool
+_shm_get_path(char *buf, size_t len, const char *name)
+{
+	int ret;
+
+	if (__predict_false(!_shmfs_path) && !_shm_check_fs()) {
+		errno = ENOTSUP;
+		return false;
+	}
+
+	/*
+	 * As per POSIX: the name should begin with a slash character.
+	 * We may disallow other slashes (implementation-defined behaviour).
+	 */
+	if (*name++ != '/' || strchr(name, '/') != NULL) {
+		errno = EINVAL;
+		return false;
+	}
+
+	ret = snprintf(buf, len, "%s/%s%s",
+	    _shmfs_path, SHMFS_OBJ_PREFIX, name);
+
+	if ((size_t)ret >= PATH_MAX) {
+		errno = ENAMETOOLONG;
+		return false;
+	}
+	return ret != -1;
+}
+
+int
+shm_open(const char *name, int oflag, mode_t mode)
+{
+	char path[PATH_MAX + 1];
+
+	if (!_shm_get_path(path, sizeof(path), name)) {
+		return -1;
+	}
+	return open(path, oflag | O_CLOEXEC | O_NOFOLLOW, mode);
+}
+
+int
+shm_unlink(const char *name)
+{
+	char path[PATH_MAX + 1];
+
+	if (!_shm_get_path(path, sizeof(path), name)) {
+		return -1;
+	}
+	return unlink(path);
+}

Reply via email to