I have been trying to read() audio data into an mmap()ed region (from a file 
just created and empty before the mmap call.  I know that read() normally
puts the data in a buffer and not a file, but with mmap() you get back a 
caddr_t pointer which I am hoping read() can use.  Here is the relevant chunk 
of code (full listing at bottom):

  /* create and memory map the target region */
  printf("0: I'm still here sir!");
  status = target = open("targetfile", O_CREAT | O_RDWR, 777);
  if (status < 0) 
    perror("error opening target file");
  printf("1: I'm still here sir!");
  region = mmap(NULL, (off_t) 512, PROT_WRITE, MAP_SHARED, target, 0);
  printf("2: I'm still here sir!");
  if (region == (caddr_t) (-1))
    perror("mmap error");

  /* record sound into mmaped region */
  printf("3: I'm still here sir!");
  status = read(audio, (void *) region, 512); 
  if (status != sizeof(region))
    perror("read screwed one way or another");

  msync(region, 512, MS_SYNC);

with the read(audio, (void *) region, 512);
line not commented out, when I run this program I get:

Bus error

and a file in the current directory:

-r----x--t   1 gandalf  gandalf         0 Feb  4 17:04 targetfile

None of the little I'm still here sir! message print with the read in there, 
so I assume I'm doing something drastic.  My questions:

1.  Why does the file have those strange permissions?  I thought I specified 
    mode 777.

2.  Is it possible to use read() into an mmap() this way?  Is there some other 
    function I should be using instead of read()?

3.  Even if it is possible, is it a completely hairbrained approach?

The full source of the short program in question:

/*
 * rawrec.c Program to test recording principle of multiple mmaps,
 * forked into the background before syncing.
 */

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>

#define LENGTH 600              /* how many seconds of the CD to store */
#define RATE 44100              /* the sampling rate */
#define SIZE 16                 /* sample size: 8 or 16 bits */
#define CHANNELS 2              /* 1 = mono 2 = stereo */

int main()
{  
  int audio;                    /* sound device file descriptor */
  int arg;                      /* argumrnt for ioctl calls */
  int status;                   /* return status of system calls */
  int target;                   /* file descriptor to write to */
  void * region;                /* for the pointer to the mapped file */

  /* open sound device */
  audio = open("/dev/dsp", O_RDWR);
  if (audio < 0) {
    perror("open of /dev/dsp failed");
    exit(1);
  }

  /* set sampling parameters */
  arg = SIZE;                   /* sample size */
  status = ioctl(audio, SOUND_PCM_WRITE_BITS, &arg);
  if (status == -1)
    perror("SOUND_PCM_WRITE_BITS ioctl fialed");
  if (arg != SIZE)
    perror("unable to set sample size");

  arg = CHANNELS; /* mono or stereo */
  status = ioctl(audio, SOUND_PCM_WRITE_CHANNELS, &arg);
  if (status == -1)
    perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
  if (arg != CHANNELS)
    perror("unable to set number of channels");

  arg = RATE;                   /* sampling rate */
  status = ioctl(audio, SOUND_PCM_WRITE_RATE, &arg);
  if (status == -1)
    perror("SOUND_PCM_WRITE_RATE ioctl failed");

  /* create and memory map the target region */
  printf("0: I'm still here sir!");
  status = target = open("targetfile", O_CREAT | O_RDWR, 777);
  if (status < 0) 
    perror("error opening target file");
  printf("1: I'm still here sir!");
  region = mmap(NULL, (off_t) 512, PROT_WRITE, MAP_SHARED, target, 0);
  printf("2: I'm still here sir!");
  if (region == (caddr_t) (-1))
    perror("mmap error");

  /* record sound into mmaped region */
  printf("3: I'm still here sir!");
  status = read(audio, (void *) region, 512); 
  if (status != sizeof(region))
    perror("read screwed one way or another");

  msync(region, 512, MS_SYNC);
}







Reply via email to