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)
125 /* Determine where the shmfs is mounted. */
126 __libc_once (once, where_is_shmfs);
128 /* If we don't know the mount points there is nothing we can do. Ever. */
129 if (mountpoint.dir == NULL)
131 __set_errno (ENOSYS);
135 /* Construct the filename. */
136 while (name[0] == '/')
141 /* The name "/" is not supported. */
142 __set_errno (EINVAL);
146 namelen = strlen (name);
147 fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
148 __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
151 /* And get the file descriptor.
152 XXX Maybe we should test each descriptor whether it really is for a
153 file on the shmfs. If this is what should be done the whole function
154 should be revamped since we can determine whether shmfs is available
155 while trying to open the file, all in one turn. */
156 return open (fname, oflag, mode);
160 /* Unlink a shared memory object. */
162 shm_unlink (const char *name)
167 /* Determine where the shmfs is mounted. */
168 __libc_once (once, where_is_shmfs);
170 if (mountpoint.dir == NULL)
172 /* We cannot find the shmfs. If `name' is really a shared
173 memory object it must have been created by another process
174 and we have no idea where that process found the mountpoint. */
175 __set_errno (ENOENT);
179 /* Construct the filename. */
180 while (name[0] == '/')
185 /* The name "/" is not supported. */
186 __set_errno (ENOENT);
190 namelen = strlen (name);
191 fname = (char *) alloca (mountpoint.dirlen + namelen + 1);
192 __mempcpy (__mempcpy (fname, mountpoint.dir, mountpoint.dirlen),
195 /* And get the file descriptor.
196 XXX Maybe we should test each descriptor whether it really is for a
197 file on the shmfs. If this is what should be done the whole function
198 should be revamped since we can determine whether shmfs is available
199 while trying to open the file, all in one turn. */
200 return unlink (fname);
207 if (mountpoint.dir != NULL && mountpoint.dir != defaultdir)
208 free (mountpoint.dir);
212 /* Make sure the table is freed if we want to free everything before
214 text_set_element (__libc_subfreeres, freeit);