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