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);
+}