[comp.unix.questions] System V shared memory

bls@u02.svl.cdc.com (Brian Scearce) (04/16/91)

I'm trying to implement a nonblocking read() and write() on our
system.  The idea is for the calls to read() and write() to fork,
so that the caller can get on with whatever it is doing.  The child
process should do the read and then change a status word for the
caller.  The caller will poll the status word.

I can't understand the shared memory system calls for System V Unix
at all.  I've been going over them for a week, and I don't feel
any closer to getting it right than when I started.  I don't have
any documentation except the man pages (please recommend some good
books).

Here's what I have so far (open and read only, write is very similar)

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "asynch.h"

int a_open(struct a_file *desc, char *name, int mode, int size)
{
  int id;

  desc->size = size;
  if ( (desc->fd = open(name, mode)) < 0) {
    return 0;
  }
  id = shmget(IPC_PRIVATE, size+sizeof(int), 0777 | IPC_CREAT);
  if (id == -1) {
    close(desc->fd);
    return 0;
  }
  desc->shmid = id;
  desc->status = (int *)shmat(id, 0, 0); /* Put status at beginning */
  if (desc->status == (int *)-1) {
    close(desc->fd);
    return 0;
  }
  desc->buffer = (char *)(desc->status + 1); /* Buffer right after */
  return 1;
}


void a_read(struct a_file *desc, int nbytes)
{
  int pid;
  int id;
  char *p;

  if ((pid = fork()) > 0) {
    *desc->status = IN_PROGRESS;
  } else if (pid < 0) {
    *desc->status = CANT_SPAWN;
  } else {

    /* This is part is the iffy bit -- what should really be here? */

    id = shmget(desc->shmid, desc->size, 0777);
    p = (char *)shmat(desc->shmid, desc->status, 0);
    if (p == -1) {
      perror("Shmat in a_read");
    }


    if (read(desc->fd, desc->buffer, nbytes) < 0)
      *desc->status = FINISH_FAIL;
    else
      *desc->status = FINISH_PASS;
    printf("done reading, status = %d\n", *desc->status);
  }
  return;
}


And here is asynch.h, with the structure:


#define CANT_SPAWN -1
#define IN_PROGRESS 0
#define FINISH_FAIL 1
#define FINISH_PASS 2

struct a_file {
  int fd;       /* File descriptor number */
  int shmid;    /* Shared memory identifier */
  int size;
  volatile char *buffer; /* Where to read the data into/out of */
  volatile int *status;  /* Status of operation */
};

int a_open(struct a_file *desc, char *name, int mode, int size);
void a_read(struct a_file *desc, int nbytes);
void a_write(struct a_file *desc, int nbytes);
int a_close(struct a_file *desc);


Thanks in advance for any help.

--
     Brian Scearce (bls@robin.svl.cdc.com  -or-  robin!bls@shamash.cdc.com)
    "Don't be surprised when a crack in the ice appears under your feet..."
 Any opinions expressed herein do not necessarily reflect CDC corporate policy.