3 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
17 #define _PATH_SHM "/dev/shm/"
24 /* Get name of dummy shm operation handle.
25 * Returns a malloc'ed buffer containing the OS specific path
26 * to the shm filename or NULL upon failure.
28 static __attribute_noinline__ char* get_shm_name(const char *name) __nonnull((1));
29 static char* get_shm_name(const char *name)
34 /* Skip leading slashes */
38 i = asprintf(&path, _PATH_SHM "%s", name);
42 path = malloc(NAME_MAX);
45 i = snprintf(path, NAME_MAX, _PATH_SHM "%s", name);
49 } else if (i >= NAME_MAX) {
51 __set_errno(ENAMETOOLONG);
58 int shm_open(const char *name, int oflag, mode_t mode)
61 char *shm_name = get_shm_name(name);
63 /* Stripped multiple '/' from start; may have set errno properly */
66 /* The FD_CLOEXEC file descriptor flag associated with the new
67 * file descriptor is set. */
69 /* Just open it with CLOEXEC set, for brevity */
70 fd = open(shm_name, oflag | O_CLOEXEC, mode);
72 fd = open(shm_name, oflag, mode);
74 fcntl(fd, F_SETFD, FD_CLOEXEC);
75 /* thus far, {G,S}ETFD only has this single flag,
76 * and setting it never fails.
77 *int fdflags = fcntl(fd, F_GETFD);
79 * fdflags = fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC);
87 if (fd < 0 && errno == EISDIR)
88 /* EISDIR is not valid for shm_open, replace it with EINVAL as glibc. */
90 free(shm_name); /* doesn't affect errno */
94 int shm_unlink(const char *name)
96 char *shm_name = get_shm_name(name);
99 /* Stripped multiple '/' from start; may have set errno properly */
100 if (shm_name == NULL)
102 ret = unlink(shm_name);
103 free(shm_name); /* doesn't affect errno */