arm: use common ret_ERRVAL
[uclibc-ng.git] / librt / shm.c
blob40e69fa2e59a72525037998af160029a46e74ab5
1 /* Copyright (C) 2009 Bernhard Reutner-Fischer <uclibc@uclibc.org>
3 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4 */
6 #include <features.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <sys/mman.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
16 #ifndef _PATH_SHM
17 #define _PATH_SHM "/dev/shm/"
18 #endif
20 #ifndef NAME_MAX
21 #define NAME_MAX 255
22 #endif
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)
31 char *path;
32 int i;
34 /* Skip leading slashes */
35 while (*name == '/')
36 ++name;
37 #ifdef __USE_GNU
38 i = asprintf(&path, _PATH_SHM "%s", name);
39 if (i < 0)
40 return NULL;
41 #else
42 path = malloc(NAME_MAX);
43 if (path == NULL)
44 return NULL;
45 i = snprintf(path, NAME_MAX, _PATH_SHM "%s", name);
46 if (i < 0) {
47 free(path);
48 return NULL;
49 } else if (i >= NAME_MAX) {
50 free(path);
51 __set_errno(ENAMETOOLONG);
52 return NULL;
54 #endif
55 return path;
58 int shm_open(const char *name, int oflag, mode_t mode)
60 int fd;
61 char *shm_name = get_shm_name(name);
63 /* Stripped multiple '/' from start; may have set errno properly */
64 if (shm_name == NULL)
65 return -1;
66 /* The FD_CLOEXEC file descriptor flag associated with the new
67 * file descriptor is set. */
68 #ifdef O_CLOEXEC
69 /* Just open it with CLOEXEC set, for brevity */
70 fd = open(shm_name, oflag | O_CLOEXEC, mode);
71 #else
72 fd = open(shm_name, oflag, mode);
73 if (fd >= 0) {
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);
78 *if (fdflags >= 0)
79 * fdflags = fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC);
80 *if (fdflags < 0) {
81 * close(fd);
82 * fd = -1;
86 #endif
87 free(shm_name); /* doesn't affect errno */
88 return fd;
91 int shm_unlink(const char *name)
93 char *shm_name = get_shm_name(name);
94 int ret;
96 /* Stripped multiple '/' from start; may have set errno properly */
97 if (shm_name == NULL)
98 return -1;
99 ret = unlink(shm_name);
100 free(shm_name); /* doesn't affect errno */
101 return ret;