bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] system V shared memory support for the Hurd in glibc


From: Marcus Brinkmann
Subject: [PATCH] system V shared memory support for the Hurd in glibc
Date: Mon, 11 Jul 2005 23:52:35 +0200
User-agent: Wanderlust/2.10.1 (Watching The Wheels) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/21.4 (i386-pc-linux-gnu) MULE/5.0 (SAKAKI)

Hi,

this patch is for glibc, but it needs to get more testing before it
can go in.  Please give it a good beating.

This patch adds System V Shared Memory support to the GNU Hurd.

There is a small extension to the filesystem interface that allows the
filesystem to report to the application if the file may currently be
mapped by other applications.  A separate patch to report this
information from ext2fs and other filesystems will follow.

These features are implemented:
Creating shared memory segments.
Attaching to them.
Detaching from them.
Removing them.
Get the uid/gid/mode.
Determine if nattch is 0 or something else.
Changing the uid/gid/mode.

These features are not, and can't be within the standard filesystem
interface:
Getting the exact number of nattch (not even if it is just 1).
Getting pid/lpid (always zero).
Getting time stamps (last attach, last detach, last modification).
Getting the cuid/cgid (always just uid/gid).
Verifying the cuid/cgid when accessing.

Compatibility note:
Most programs should work.
POSIX says RMID removes all mappings, but no system does it that way
(and neither do we).


2005-07-11  Marcus Brinkmann  <address@hidden>

        * sysdeps/mach/hurd/bits/stat.h (S_IMMAP0): New macro.
        (S_ISPARE): Unset the S_IMMAP0 flag.
        * sysdeps/mach/hurd/ftok.c: New file.
        * sysdeps/mach/hurd/shmat.c: New file.
        * sysdeps/mach/hurd/shmctl.c: New file.
        * sysdeps/mach/hurd/shmdt.c: New file.
        * sysdeps/mach/hurd/sysvshm.h: New file.
        * sysdeps/mach/hurd/sysvshm.c: New file.


diff -rupN libc/sysdeps/mach/hurd/bits/stat.h 
libc-shm/sysdeps/mach/hurd/bits/stat.h
*** libc/sysdeps/mach/hurd/bits/stat.h  2001-07-06 06:55:58.000000000 +0200
--- libc-shm/sysdeps/mach/hurd/bits/stat.h      2005-07-11 22:58:05.000000000 
+0200
***************
*** 1,4 ****
! /* Copyright (C) 1992, 93, 94, 96, 97, 99, 2000 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
  
     The GNU C Library is free software; you can redistribute it and/or
--- 1,4 ----
! /* Copyright (C) 1992,93,94,96,97,99,2000,2005 Free Software Foundation, Inc.
     This file is part of the GNU C Library.
  
     The GNU C Library is free software; you can redistribute it and/or
***************
*** 182,189 ****
  /* All the bits relevant to translators */
  #define S_ITRANS      000070000000
  
  /* ALL the unused bits.  */
! #define       S_ISPARE        (~(S_IFMT|S_ITRANS|S_INOCACHE|    \
                           S_IUSEUNK|S_IUNKNOWN|07777))
  #endif
  
--- 182,192 ----
  /* All the bits relevant to translators */
  #define S_ITRANS      000070000000
  
+ /* Definitely no mmaps to this.  */
+ #define S_IMMAP0      000100000000
+ 
  /* ALL the unused bits.  */
! #define       S_ISPARE        (~(S_IFMT|S_ITRANS|S_INOCACHE|S_IMMAP0|    \
                           S_IUSEUNK|S_IUNKNOWN|07777))
  #endif
  
diff -rupN libc/sysdeps/mach/hurd/ftok.c libc-shm/sysdeps/mach/hurd/ftok.c
*** libc/sysdeps/mach/hurd/ftok.c       1970-01-01 01:00:00.000000000 +0100
--- libc-shm/sysdeps/mach/hurd/ftok.c   2005-07-11 22:57:25.000000000 +0200
***************
*** 0,-1 ****
--- 1,43 ----
+ /* Copyright (C) 1995, 1996, 2000, 2005 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Ulrich Drepper <address@hidden>, August 1995.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
+ #include <sys/ipc.h>
+ #include <sys/stat.h>
+ 
+ 
+ /* In the Hurd, we use the second-to-most-significant bit as flag for
+    private keys.  We use a different order of the components so that
+    the biggest one---the inode number---is affected by this.  */
+ 
+ key_t
+ ftok (pathname, proj_id)
+      const char *pathname;
+      int proj_id;
+ {
+   struct stat64 st;
+   key_t key;
+ 
+   if (__xstat64 (_STAT_VER, pathname, &st) < 0)
+     return (key_t) -1;
+ 
+   key = ((st.st_dev & 0xff) | ((proj_id & 0xff) << 8)
+        | ((st.st_ino & 0x3fff) << 16));
+ 
+   return key;
+ }
diff -rupN libc/sysdeps/mach/hurd/shmat.c libc-shm/sysdeps/mach/hurd/shmat.c
*** libc/sysdeps/mach/hurd/shmat.c      1970-01-01 01:00:00.000000000 +0100
--- libc-shm/sysdeps/mach/hurd/shmat.c  2005-07-11 22:57:25.000000000 +0200
***************
*** 0,-1 ****
--- 1,77 ----
+ /* Copyright (C) 2005 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
+ #include <errno.h>
+ #include <utime.h>
+ #include <stdio.h>
+ #include <assert.h>
+ #include <sys/mman.h>
+ #include <sys/ipc.h>
+ #include <sys/shm.h>
+ #include <sys/time.h>
+ #include <sys/stat.h>
+ 
+ #include "sysvshm.h"
+ 
+ /* Attach the shared memory segment associated with SHMID to the data
+    segment of the calling process.  SHMADDR and SHMFLG determine how
+    and where the segment is attached.  */
+ void *
+ __shmat (int shmid, const void *shmaddr, int shmflg)
+ {
+   error_t err;
+   char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX];
+   int fd;
+   void *addr;
+   struct stat statbuf;
+   int res;
+ 
+   sprintf (filename, SHM_DIR SHM_NAMEPRI, shmid);
+   fd = __open (filename, (shmflg & SHM_RDONLY) ? O_RDONLY : O_RDWR);
+   if (fd < 0)
+     {
+       if (errno == ENOENT)
+       errno = EINVAL;
+       return (void *) -1;
+     }
+ 
+   res = __fstat (fd, &statbuf);
+   if (res < 0)
+     {
+       __close (fd);
+       return (void *) -1;
+     }
+ 
+   addr = __mmap ((void *) shmaddr, statbuf.st_size,
+                PROT_READ | ((shmflg & SHM_RDONLY) ? 0 : PROT_WRITE),
+                MAP_SHARED, fd, 0);
+   __close (fd);
+   if (addr == MAP_FAILED)
+     return (void *) -1;
+ 
+   err = __sysvshm_add (addr, statbuf.st_size);
+   if (err)
+     {
+       munmap (addr, statbuf.st_size);
+       return (void *) -1;
+     }
+ 
+   return addr;
+ }
+ 
+ weak_alias(__shmat, shmat)
diff -rupN libc/sysdeps/mach/hurd/shmctl.c libc-shm/sysdeps/mach/hurd/shmctl.c
*** libc/sysdeps/mach/hurd/shmctl.c     1970-01-01 01:00:00.000000000 +0100
--- libc-shm/sysdeps/mach/hurd/shmctl.c 2005-07-11 22:57:25.000000000 +0200
***************
*** 0,-1 ****
--- 1,130 ----
+ /* Copyright (C) 2005 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
+ #include <errno.h>
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <sys/mman.h>
+ #include <sys/ipc.h>
+ #include <sys/shm.h>
+ #include <sys/stat.h>
+ 
+ #include "sysvshm.h"
+ 
+ /* Provide operations to control over shared memory segments.  */
+ int
+ __shmctl (int id, int cmd, struct shmid_ds *buf)
+ {
+   error_t err = 0;
+   int res;
+   char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX];
+   struct stat statbuf;
+ 
+   sprintf (filename, SHM_DIR SHM_NAMEPRI, id);
+   /* SysV requires read access for IPC_STAT.  */
+   fd = __open (filename, O_NORW);
+   if (fd < 0)
+     {
+       if (errno == ENOENT)
+       errno = EINVAL;
+       return -1;
+     }
+ 
+   res = __fstat (fd, &statbuf);
+   if (res < 0)
+     {
+       err = errno;
+       __close (fd);
+       errno = err;
+       return -1;
+     }
+   
+   switch (cmd)
+     {
+     case IPC_STAT:
+ 
+       buf->shm_perm.__key = id;
+       buf->shm_perm.uid = statbuf.st_uid;
+       buf->shm_perm.gid = statbuf.st_gid;
+ 
+       /* We do not support the creator.  */
+       buf->shm_perm.cuid = statbuf.st_uid;
+       buf->shm_perm.cgid = statbuf.st_gid;
+ 
+       /* We just want the protection bits.  */
+       buf->shm_perm.mode = statbuf.st_mode & 0777;
+       /* Hopeless.  We do not support a sequence number.  */
+       buf->shm_perm.__seq = statbuf.st_ino;
+       buf->shm_segsz = statbuf.st_size;
+ 
+       /* Hopeless.  We do not support any of these.  */
+       buf->shm_atime = statbuf.st_atime;
+       buf->shm_dtime = statbuf.st_mtime;
+       /* Well, this comes at least close.  */
+       buf->shm_ctime = statbuf.st_ctime;
+ 
+       /* We do not support the PID.  */
+       buf->shm_cpid = 0;
+       buf->shm_lpid = 0;
+ 
+       if (statbuf.st_mode & S_IMMAP0)
+         buf->shm_nattch = 0;
+       else
+         /* 42 is the answer.  Of course this is bogus, but for most
+          applications, this should be fine.  */
+         buf->shm_nattch = 42;
+ 
+       break;
+ 
+     case IPC_SET:
+       if (statbuf.st_uid != buf->shm_perm.uid
+         || statbuf.st_gid != buf->shm_perm.gid)
+       {
+         res = __fchown (fd,
+                         (statbuf.st_uid != buf->shm_perm.uid)
+                         ? buf->shm_perm.uid : -1,
+                         (statbuf.st_gid != buf->shm_perm.gid)
+                         ? buf->shm_perm.gid : -1);
+         if (res < 0)
+           err = errno;
+       }
+ 
+       if (!err && statbuf.st_mode & 0777 != buf->shm_perm.mode & 0777)
+       {
+         res = __fchmod (fd, (statbuf.st_mode & ~0777)
+                         | (buf->shm_perm.mode & 0777));
+         if (res < 0)
+           err = errno;
+       }
+       break;
+ 
+     case IPC_RMID:
+       res = __unlink (filename);
+       /* FIXME: Check error (mapping ENOENT to EINVAL).  */
+       break;
+ 
+     default:
+       err = EINVAL;
+     }
+ 
+   __close (fd);
+   errno = err;
+   return err ? -1 : 0;
+ }
+ 
+ weak_alias(__shmctl, shmctl)
diff -rupN libc/sysdeps/mach/hurd/shmdt.c libc-shm/sysdeps/mach/hurd/shmdt.c
*** libc/sysdeps/mach/hurd/shmdt.c      1970-01-01 01:00:00.000000000 +0100
--- libc-shm/sysdeps/mach/hurd/shmdt.c  2005-07-11 22:57:25.000000000 +0200
***************
*** 0,-1 ****
--- 1,51 ----
+ /* Copyright (C) 2005 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
+ #include <stdio.h>
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <assert.h>
+ #include <sys/mman.h>
+ #include <sys/ipc.h>
+ #include <sys/shm.h>
+ #include <sys/time.h>
+ #include <sys/stat.h>
+ 
+ #include "sysvshm.h"
+ 
+ /* Detach shared memory segment starting at address specified by
+    SHMADDR from the caller's data segment.  */
+ int
+ __shmdt (const void *shmaddr)
+ {
+   error_t err;
+   size_t size;
+ 
+   err = __sysvshm_remove ((void *) shmaddr, &size);
+   if (err)
+     {
+       errno = err;
+       return -1;
+     }
+ 
+   __munmap ((void *) shmaddr, size);
+   return 0;
+ }
+ 
+ weak_alias(__shmdt, shmdt)
diff -rupN libc/sysdeps/mach/hurd/shmget.c libc-shm/sysdeps/mach/hurd/shmget.c
*** libc/sysdeps/mach/hurd/shmget.c     1970-01-01 01:00:00.000000000 +0100
--- libc-shm/sysdeps/mach/hurd/shmget.c 2005-07-11 22:57:25.000000000 +0200
***************
*** 0,-1 ****
--- 1,245 ----
+ /* Copyright (C) 2005 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
+ #include <stdbool.h>
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <sys/shm.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <limits.h>
+ #include <stdio.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ 
+ #include <hurd/fd.h>
+ 
+ #include "sysvshm.h"
+ 
+ /* Create a new shared memory segment file without linking it into the
+    filesystem.  Return the directory and file ports in R_DIR and R_FILE.  */
+ static error_t
+ create_shm_file (size_t size, int flags, file_t *r_dir, file_t *r_file)
+ {
+   error_t err;
+   file_t dir;
+   file_t file;
+ 
+   flags &= 0777;
+ 
+   /* Get a port to the directory that will contain the file.  */
+   dir = __file_name_lookup (SHM_DIR, 0, 0);
+   if (dir == MACH_PORT_NULL)
+     return errno;
+ 
+   /* Create an unnamed file in the directory.  */
+   err = __dir_mkfile (dir, O_RDWR, flags, &file);
+   if (err)
+     {
+       __mach_port_deallocate (__mach_task_self (), dir);
+       return err;
+     }
+ 
+   err = __file_set_size (file, size);
+   if (err)
+     {
+       __mach_port_deallocate (__mach_task_self (), file);
+       __mach_port_deallocate (__mach_task_self (), dir);
+ 
+       return err;
+     }
+ 
+   *r_dir = dir;
+   *r_file = file;
+ 
+   return 0;
+ }
+   
+ 
+ /* Open the shared memory segment *R_KEY and return a file descriptor
+    to it in R_FD.  If KEY is IPC_PRIVATE, use a private key and return
+    it in R_KEY.  */
+ static error_t
+ get_exclusive (int shmflags, size_t size, key_t *r_key, int *r_fd)
+ {
+   error_t err;
+   file_t dir;
+   file_t file;
+   char filename[SHM_NAMEMAX];
+   key_t key = *r_key;
+   bool is_private;
+ 
+   /* Create the shared memory segment.  */
+   err = create_shm_file (size, shmflags, &dir, &file);
+   if (err)
+     return err;
+ 
+   if (key == IPC_PRIVATE)
+     {
+       is_private = true;
+       key = SHM_PRIV_KEY_START;
+ 
+       /* Try to link the shared memory segment into the filesystem
+        (exclusively).  Private segments have negative keys.  */
+       do
+       {
+         sprintf (filename, SHM_NAMEPRI, key);
+         err = __dir_link (dir, file, filename, 1);
+         if (!err)
+           {
+             /* We are done.  */
+             *r_key = key;
+             break;
+           }
+         else if (err == EEXIST)
+           {
+             /* Check if we ran out of keys.  If not, try again with new
+                key.  */
+             if (key == SHM_PRIV_KEY_END)
+               err = ENOSPC;
+             else
+               err = 0;
+ 
+             key--;
+           }
+       }
+       while (!err);
+     }
+   else
+     {
+       /* Try to link the shared memory segment into the filesystem
+        (exclusively) under the given key.  */
+       sprintf (filename, SHM_NAMEPRI, key);
+       err = __dir_link (dir, file, filename, 1);
+     }
+ 
+   __mach_port_deallocate (__mach_task_self (), dir);
+ 
+   if (!err)
+     {
+       int fd;
+ 
+       /* Get a file descriptor for that port.  */
+       fd = _hurd_intern_fd (file, O_RDWR, 1); /* dealloc on error */
+       if (fd < 0)
+       err = errno;
+       else
+       *r_fd = fd;
+     }
+ 
+   return err;
+ }
+ 
+ 
+ /* Open the shared memory segment KEY (creating it if it doesn't yet
+    exist) and return a file descriptor to it in R_FD.  */
+ static error_t
+ get_shared (int shmflags, size_t size, key_t key, int *r_fd)
+ {
+   error_t err = 0;
+   char filename[sizeof (SHM_DIR) - 1 + SHM_NAMEMAX];
+   int fd = -1;
+   int create_flag;
+ 
+   create_flag = (shmflags & IPC_CREAT) ? O_CREAT : 0;
+   sprintf (filename, SHM_DIR SHM_NAMEPRI, key);
+ 
+   do
+     {
+       fd = __open (filename, O_NORW | create_flag, shmflags & 0777);
+ 
+       if (fd < 0 && errno != ENOENT)
+       /* We give up.  */
+       return errno;
+       else if (fd >= 0)
+       {
+         int res;
+         struct stat statbuf;
+ 
+         /* Check the size (we only need to do this if we did not
+            create the shared memory segment file ourselves).  */
+         res = __fstat (fd, &statbuf);
+         if (res < 0)
+           {
+             err = errno;
+             __close (fd);
+             return err;
+           }
+ 
+         if (statbuf.st_size < size)
+           {
+             __close (fd);
+             return EINVAL;
+           }
+       }         
+       else
+       {
+         /* The memory segment doesn't exist.  */
+         if (create_flag)
+           {
+             /* Try to create it exclusively.  */
+             err = get_exclusive (shmflags, size, &key, &fd);
+             if (err == EEXIST)
+               /* If somebody created it in the meanwhile, just try again.  */
+               err = 0;
+           }
+         else
+           err = ENOENT;
+       }
+     }
+   while (fd < 0 && !err);
+ 
+   if (!err)
+     *r_fd = fd;
+   else
+     *r_fd = -1;
+ 
+   return err;
+ }
+ 
+ /* Return an identifier for an shared memory segment of at least size
+    SIZE which is associated with KEY.  */
+ int
+ __shmget (key_t key, size_t size, int shmflags)
+ {
+   error_t err;
+   int fd;
+ 
+   if (key == IPC_PRIVATE || shmflags & IPC_EXCL)
+     /* An exclusive shared memory segment must be created.  */
+     err = get_exclusive (shmflags, size, &key, &fd);
+   else
+     err = get_shared (shmflags, size, key, &fd);
+ 
+   if (err)
+     {
+       errno = err;
+       return -1;
+     }
+ 
+   /* From here, we can't fail.  That's important, as otherwise we
+      would need to unlink the file if we created it (in that case, the
+      code above would have to be changed to pass a "created" flag down
+      to the caller).  */
+ 
+   __close (fd);
+ 
+   return key;
+ }
+ 
+ weak_alias(__shmget, shmget)
diff -rupN libc/sysdeps/mach/hurd/sysvshm.c libc-shm/sysdeps/mach/hurd/sysvshm.c
*** libc/sysdeps/mach/hurd/sysvshm.c    1970-01-01 01:00:00.000000000 +0100
--- libc-shm/sysdeps/mach/hurd/sysvshm.c        2005-07-11 22:57:25.000000000 
+0200
***************
*** 0,-1 ****
--- 1,96 ----
+ /* Copyright (C) 2005 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
+ #include <string.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <stddef.h>
+ #include <errno.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <dirent.h>
+ #include <sys/stat.h>
+ #include <sys/shm.h>
+ 
+ 
+ /* Description of an shm attachment.  */
+ struct sysvshm_attach
+ {
+   /* Linked list.  */
+   struct sysvshm_attach *next;
+ 
+   /* Map address.  */
+   void *addr;
+ 
+   /* Map size.  */
+   size_t size;
+ };
+ 
+ /* List of attachments.  */
+ static struct sysvshm_attach *attach_list;
+ 
+ /* A lock to protect the linked list of shared memory attachments.  */
+ static struct mutex sysvshm_lock = MUTEX_INITIALIZER;
+ 
+ 
+ /* Adds a segment attachment.  */
+ error_t
+ __sysvshm_add (void *addr, size_t size)
+ {
+   struct sysvshm_attach *shm;
+ 
+   shm = malloc (sizeof (*shm));
+   if (!shm)
+     return errno;
+ 
+   __mutex_lock (&sysvshm_lock);
+   shm->addr = addr;
+   shm->size = size;
+   shm->next = attach_list;
+   attach_list = shm;
+   __mutex_unlock (&sysvshm_lock);
+ 
+   return 0;
+ }
+ 
+ /* Removes a segment attachment.  Returns its size if found, or EINVAL
+    otherwise.  */
+ error_t
+ __sysvshm_remove (void *addr, size_t *size)
+ {
+   struct sysvshm_attach *shm;
+   struct sysvshm_attach **pshm = &attach_list;
+ 
+   __mutex_lock (&sysvshm_lock);
+   shm = attach_list;
+   while (shm)
+     {
+       shm = *pshm;
+       if (shm->addr == addr)
+       {
+         *pshm = shm->next;
+         *size = shm->size;
+         __mutex_unlock (&sysvshm_lock);
+         return 0;
+       }
+       pshm = &shm->next;
+       shm = shm->next;
+     }
+   __mutex_unlock (&sysvshm_lock);
+   return EINVAL;
+ }
diff -rupN libc/sysdeps/mach/hurd/sysvshm.h libc-shm/sysdeps/mach/hurd/sysvshm.h
*** libc/sysdeps/mach/hurd/sysvshm.h    1970-01-01 01:00:00.000000000 +0100
--- libc-shm/sysdeps/mach/hurd/sysvshm.h        2005-07-11 22:57:25.000000000 
+0200
***************
*** 0,-1 ****
--- 1,47 ----
+ /* Copyright (C) 2005 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+ 
+    The GNU C Library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+ 
+    The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with the GNU C Library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA.  */
+ 
+ #include <paths.h>
+ #include <hurd.h>
+ 
+ /* The area (from top to bottom) that is used for private keys.  These
+    are all keys that have the second highest bit set.  */
+ #define SHM_PRIV_KEY_START INT_MAX
+ #define SHM_PRIV_KEY_END ((INT_MAX / 2) + 1)
+ 
+ #define SHM_PREFIX "shm-"
+ #define SHM_DIR _PATH_DEV "shm/"
+ 
+ /* The maximum number of characters in a shared memory segment file name.
+    32 is the max number of characters in a 128 bit number in hex.  */
+ #if __WORDSIZE > 128
+ #error Need to increase SHM_NAMEMAX.
+ #else
+ #define SHM_NAMEMAX (sizeof (SHM_PREFIX) - 1 + 32 + 1)
+ #endif
+ 
+ /* Use this with printf and its variants.  */
+ #define SHM_NAMEPRI SHM_PREFIX "%0x"
+ 
+ 
+ /* Adds a segment attachment.  */
+ error_t __sysvshm_add (void *addr, size_t size);
+ 
+ /* Removes a segment attachment.  Returns its size if found, or EINVAL
+    otherwise.  */
+ error_t __sysvshm_remove (void *addr, size_t *size);






reply via email to

[Prev in Thread] Current Thread [Next in Thread]