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>
32 /* XXX Currently the Linux kernel sources do not define a super magic number
33 for the shmfs and the kernel assigns the value 0 to f_type. */
34 #ifndef SHMFS_SUPER_MAGIC
35 # define SHMFS_SUPER_MAGIC 0
38 /* Mount point of the shared memory filesystem. */
45 /* This is the default directory. */
46 const char defaultdir[] = "/var/shm/";
48 /* Protect the `mountpoint' variable above. */
49 __libc_once_define (static, once);
52 /* Determine where the shmfs is mounted (if at all). */
62 /* The canonical place is /var/shm. This is at least what the
63 documentation tells everybody to do. */
64 if (__statfs ("/var/shm", &f) == 0 && f.f_type == SHMFS_SUPER_MAGIC)
66 /* It is in the normal place. */
67 mountpoint.dir = (char *) defaultdir;
68 mountpoint.dirlen = strlen ("/var/shm/");
73 /* OK, do it the hard way. Look through the /proc/mounts file and if
74 this does not exist through /etc/fstab to find the mount point. */
75 fp = __setmntent ("/proc/mounts", "r");
76 if (__builtin_expect (fp == NULL, 0))
78 fp = __setmntent (_PATH_MNTTAB, "r");
79 if (__builtin_expect (fp == NULL, 0))
80 /* There is nothing we can do. Blind guesses are not helpful. */
84 /* Now read the entries. */
85 while ((mp = __getmntent_r (fp, &resmem, buf, sizeof buf)) != NULL)
86 if (strcmp (mp->mnt_type, "shm") == 0)
88 /* Found it. There might be more than one place where the
89 filesystem is mounted but one is enough for us. */
90 size_t namelen = strlen (mp->mnt_dir);
93 /* Hum, maybe some crippled entry. Keep on searching. */
96 mountpoint.dir = (char *) malloc (namelen + 2);
97 if (mountpoint.dir != NULL)
99 char *cp = __mempcpy (mountpoint.dir, mp->mnt_dir, namelen);
103 mountpoint.dirlen = cp - mountpoint.dir;
109 /* Close the stream. */
114 /* Open shared memory object. This implementation assumes the shmfs
115 implementation introduced in the late 2.3.x kernel series to be
116 available. Normally the filesystem will be mounted at /var/shm but
117 we fall back on searching for the actual mount point should opening
120 shm_open (const char *name, int oflag, mode_t mode)
126 /* Determine where the shmfs is mounted. */
127 __libc_once (once, where_is_shmfs);
129 /* If we don't know the mount points there is nothing we can do. Ever. */
130 if (mountpoint.dir == NULL)
132 __set_errno (ENOSYS);
136 /* Construct the filename. */
137 while (name[0] == '/')
142 /* The name "/" is not supported. */
143 __set_errno (EINVAL);
147 namelen = strlen (name);
148 fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
149 __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
152 /* And get the file descriptor.
153 XXX Maybe we should test each descriptor whether it really is for a
154 file on the shmfs. If this is what should be done the whole function
155 should be revamped since we can determine whether shmfs is available
156 while trying to open the file, all in one turn. */
157 fd = open (fname, oflag, mode);
160 /* We got a descriptor. Now set the FD_CLOEXEC bit. */
161 int flags = fcntl (fd, F_GETFD, 0);
163 if (__builtin_expect (flags, 0) >= 0)
166 flags = fcntl (fd, F_SETFD, flags);
171 /* Something went wrong. We cannot return the descriptor. */
172 int save_errno = errno;
175 __set_errno (save_errno);
183 /* Unlink a shared memory object. */
185 shm_unlink (const char *name)
190 /* Determine where the shmfs is mounted. */
191 __libc_once (once, where_is_shmfs);
193 if (mountpoint.dir == NULL)
195 /* We cannot find the shmfs. If `name' is really a shared
196 memory object it must have been created by another process
197 and we have no idea where that process found the mountpoint. */
198 __set_errno (ENOENT);
202 /* Construct the filename. */
203 while (name[0] == '/')
208 /* The name "/" is not supported. */
209 __set_errno (ENOENT);
213 namelen = strlen (name);
214 fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
215 __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
218 /* And get the file descriptor.
219 XXX Maybe we should test each descriptor whether it really is for a
220 file on the shmfs. If this is what should be done the whole function
221 should be revamped since we can determine whether shmfs is available
222 while trying to open the file, all in one turn. */
223 return unlink (fname);
230 if (mountpoint.dir != NULL && mountpoint.dir != defaultdir)
231 free (mountpoint.dir);
235 /* Make sure the table is freed if we want to free everything before
237 text_set_element (__libc_subfreeres, freeit);