[Top][All Lists]

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

Re: Linux style /proc filesystem translator

From: Jon Arney
Subject: Re: Linux style /proc filesystem translator
Date: Fri, 22 Mar 2002 13:48:35 -0700


Correct me if my interpretation of those links is incorrect.  My
understanding of what you're shooting for is a translator free
implementation.  i.e. You would like to see an implementation which
merely maps the shm* calls into existing filesystem calls.

For instance, rather than having a shm_stat RPC, we might just
perform the mapping in libc.  Instead of a shm_statall RPC, we
might just lookup the directory containing the SHM files (using
whatever translator is set to /tmp/shm/) and perform 'stat' on
each of them.  Instead of the shm_getid RPC, we might just come
up with a uniform algorithm (like the assignment operator) for
mapping SHM<--->SHM IDs.

This is not yet fully baked, but I have a sort-of outline of
what it might take.  The following functions would go
into 'libc' (when finished), and no new translators would
have to be created.  (Error checking here very poor for the
sake of clarity of flow).

Is this the approach you were looking for?  If so, I'll finish
it up, and if not, let me know if I'm completely missing the

If this is the approach you're looking for, sysv message queues
and semaphores can use the same approach fairly easily.

int do_sysvipc_shmget(key_t key, int size, int shmflag)
  char data = 0;
  int fd;
  int err;
  sysvipc_shm_t *shm;


  shm = (sysvipc_shm_t *)malloc(sizeof (sysvipc_shm_t));
  if (!shm) {
    return -1;

  sysvipc_shmpath(shm->pathname, key);
  fd = open(shm->pathname,
            O_RDWR | 
            ((shmflag & IPC_CREAT) ? O_CREAT : 0) | 
            ((shmflag & IPC_EXCL) ? O_EXCL : 0),
            (shmflag & 0777));

  if (fd == -1) {
    return -1;

  sysvipc_userpath(shm->userpath, key);

   * If we're creating the file, zero fill it for
   * the specified length.
  if (shmflag & IPC_CREAT) {
    err = lseek(fd, size-1, SEEK_SET);
    if (err == -1) {
      return err;
    err = write(fd, &data, 1);
    if (err != 1) {

  shm->key = key;
  shm->id = sysvipc_shm_key_to_id(key);
  shm->fd = fd;
  shm->length = size;
  list_add_tail(&shm->list, &head);

  return key;

void *do_sysvipc_shmat ( int shmid, const void *shmaddr, int shmflg )
  sysvipc_shm_t *shm;
  void *addr;


  shm = sysvipc_lookup_id(shmid);
  if (!shm) {
    errno = EINVAL;
    return NULL;

  addr = mmap(NULL, shm->length,
              PROT_READ | ((shmflg & SHM_RDONLY) ? 0 : PROT_WRITE),
              shm->fd, 0);

  shm->addr = addr;
  link(shm->pathname, shm->userpath); /* Let them know we're here */

  return (void *)addr;

int do_sysvipc_shmdt(const void *shmaddr)
  sysvipc_shm_t *shm;
  int err;


  shm = sysvipc_lookup_addr(shmaddr);
  if (!shm) {
    errno = EINVAL;
    return 0;

  err = munmap(shm->addr, shm->length);
  err = close(shm->fd);
  unlink(shm->userpath); /* Let them know we've left the building */

  return err;

int do_sysvipc_shmctl(int shmid, int cmd, struct shmid_ds *buf)
  int err = 0;
  sysvipc_shm_t *shm;
  struct stat statbuf;

  shm = sysvipc_lookup_id(shmid);
  if (!shm) {
    errno = EINVAL;
    return -1;

  err = fstat(shm->fd, &statbuf);
  if (err) return err;

  switch (cmd) {
  case IPC_STAT:
    /* shmid_ds contains: */
    /* Map file stats into shm stats */
    buf->shm_perm.__key = 0;
    buf->shm_perm.uid = statbuf.st_uid;
    buf->shm_perm.gid = statbuf.st_gid;
    buf->shm_perm.cuid = statbuf.st_uid;
    buf->shm_perm.cgid = statbuf.st_gid;
    buf->shm_perm.mode = statbuf.st_mode;
    buf->shm_perm.__seq = statbuf.st_ino; /*XXX*/
    buf->shm_segsz = statbuf.st_size;
    buf->shm_atime = statbuf.st_atime; /*XXX*/
    buf->shm_dtime = statbuf.st_atime; /*XXX*/
    buf->shm_ctime = statbuf.st_ctime;
    buf->shm_cpid = 0;
    buf->shm_lpid = 0;
    buf->shm_nattch = statbuf.st_nlink-1;
  case IPC_SET:
    err = 0; /* NOT YET IMPLEMENTED */
  case IPC_RMID:
    /* Remove the real node only if there are no others attached */
    /* Note! this is a potential race condition if someone */
    /* attaches after our stat! */
    if (buf->shm_nattch == 1) {
      err = unlink(shm->pathname);
    errno = EINVAL;
    err = -1;

  return err;

Marcus Brinkmann wrote:
> On Thu, Mar 21, 2002 at 11:05:21PM -0700, Jon Arney wrote:
> > James,
> >
> > Thanks for the links.  One of the difficult things about coming up to
> > speed on the Hurd is that there are so many different websites with
> > lots of (sometimes conflicting) information.
> This mailing list is the place to clear everything up.
> > The Debian/Hurd site said
> Uh, I have to update that... most of it is stale.
> > One question I had was about your list of planned changes.  On there,
> > you list "Posix shared memory".  Is anybody working on this?  If not,
> > I'd like to make an attempt at it (I have already started working on
> > some of it).  If there's already a project partially completed, that
> > would be better than starting from scratch.  I can't seem to get
> > my Gimp to work because it lacks shmget/shmat/etc.
> Yes, this would be nice to have, a couple of programs require it.
> I have dug out two links for this, which you should carefully read (and
> the follow ups):
> http://mail.gnu.org/pipermail/bug-hurd/2001-May/004172.html
> http://mail.gnu.org/pipermail/bug-hurd/2001-May/004173.html
> In these mails you will find a shm implementation by Neal Walfield.
> However, we still want to have the internal interface that is used to be
> the Hurd file interface, so this needs to be reworked.  However, the
> issues that were raised have to be adressed.  So you can use the
> discussions and Neal's code as a jumping board to get right into the
> heart of the matter.
> And I think there are still some bugs in tmpfs that need to be fixed.
> Thanks,
> Marcus

Jonathan S. Arney
Software Engineer
(602) - 589 - 6654

reply via email to

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