1 /* Copyright (C) 2000 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
28 #include <sys/statfs.h>
29 #include <bits/libc-lock.h>
30 #include "linux_fsinfo.h"
33 /* Mount point of the shared memory filesystem. */
40 /* This is the default directory. */
41 const char defaultdir[] = "/var/shm/";
43 /* Protect the `mountpoint' variable above. */
44 __libc_once_define (static, once);
47 /* Determine where the shmfs is mounted (if at all). */
57 /* The canonical place is /var/shm. This is at least what the
58 documentation tells everybody to do. */
59 if (__statfs ("/var/shm", &f) == 0 && f.f_type == SHMFS_SUPER_MAGIC)
61 /* It is in the normal place. */
62 mountpoint.dir = (char *) defaultdir;
63 mountpoint.dirlen = strlen ("/var/shm/");
68 /* OK, do it the hard way. Look through the /proc/mounts file and if
69 this does not exist through /etc/fstab to find the mount point. */
70 fp = __setmntent ("/proc/mounts", "r");
71 if (__builtin_expect (fp == NULL, 0))
73 fp = __setmntent (_PATH_MNTTAB, "r");
74 if (__builtin_expect (fp == NULL, 0))
75 /* There is nothing we can do. Blind guesses are not helpful. */
79 /* Now read the entries. */
80 while ((mp = __getmntent_r (fp, &resmem, buf, sizeof buf)) != NULL)
81 if (strcmp (mp->mnt_type, "shm") == 0)
83 /* Found it. There might be more than one place where the
84 filesystem is mounted but one is enough for us. */
85 size_t namelen = strlen (mp->mnt_dir);
88 /* Hum, maybe some crippled entry. Keep on searching. */
91 mountpoint.dir = (char *) malloc (namelen + 2);
92 if (mountpoint.dir != NULL)
94 char *cp = __mempcpy (mountpoint.dir, mp->mnt_dir, namelen);
98 mountpoint.dirlen = cp - mountpoint.dir;
104 /* Close the stream. */
109 /* Open shared memory object. This implementation assumes the shmfs
110 implementation introduced in the late 2.3.x kernel series to be
111 available. Normally the filesystem will be mounted at /var/shm but
112 we fall back on searching for the actual mount point should opening
115 shm_open (const char *name, int oflag, mode_t mode)
121 /* Determine where the shmfs is mounted. */
122 __libc_once (once, where_is_shmfs);
124 /* If we don't know the mount points there is nothing we can do. Ever. */
125 if (mountpoint.dir == NULL)
127 __set_errno (ENOSYS);
131 /* Construct the filename. */
132 while (name[0] == '/')
137 /* The name "/" is not supported. */
138 __set_errno (EINVAL);
142 namelen = strlen (name);
143 fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
144 __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
147 /* And get the file descriptor.
148 XXX Maybe we should test each descriptor whether it really is for a
149 file on the shmfs. If this is what should be done the whole function
150 should be revamped since we can determine whether shmfs is available
151 while trying to open the file, all in one turn. */
152 fd = open (fname, oflag, mode);
155 /* We got a descriptor. Now set the FD_CLOEXEC bit. */
156 int flags = fcntl (fd, F_GETFD, 0);
158 if (__builtin_expect (flags, 0) >= 0)
161 flags = fcntl (fd, F_SETFD, flags);
166 /* Something went wrong. We cannot return the descriptor. */
167 int save_errno = errno;
170 __set_errno (save_errno);
178 /* Unlink a shared memory object. */
180 shm_unlink (const char *name)
185 /* Determine where the shmfs is mounted. */
186 __libc_once (once, where_is_shmfs);
188 if (mountpoint.dir == NULL)
190 /* We cannot find the shmfs. If `name' is really a shared
191 memory object it must have been created by another process
192 and we have no idea where that process found the mountpoint. */
193 __set_errno (ENOENT);
197 /* Construct the filename. */
198 while (name[0] == '/')
203 /* The name "/" is not supported. */
204 __set_errno (ENOENT);
208 namelen = strlen (name);
209 fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
210 __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
213 /* And get the file descriptor.
214 XXX Maybe we should test each descriptor whether it really is for a
215 file on the shmfs. If this is what should be done the whole function
216 should be revamped since we can determine whether shmfs is available
217 while trying to open the file, all in one turn. */
218 return unlink (fname);
225 if (mountpoint.dir != NULL && mountpoint.dir != defaultdir)
226 free (mountpoint.dir);
230 /* Make sure the table is freed if we want to free everything before
232 text_set_element (__libc_subfreeres, freeit);