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); }