Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Memory-Mapped Files Programming language: c (under Linu) Modify the mmap-write a

ID: 3736481 • Letter: M

Question

Memory-Mapped Files
Programming language: c (under Linu)

Modify the mmap-write and mmap-read programs such that the former write n ran-
dom integers to the file and the latter reads and prints all integers. n is an argument to
both programs. It must be greater than zero. Include error handling when parsing the
argument n and for the system calls open() and mmap().


Example executions:
$ make
$ ./mmap-write /tmp/afile 10
$ cat /tmp/afile
-68 7 24 -10 48 24 -50 -97 52 -60
./mmap-read /tmp/afile 10
-68 7 24 -10 48 24 -50 -97 52 -60
$ ./mmap-write /tmp/afile 0
invalid number of integers
$ ./mmap-write /tmp/afile x
failed to parse number of integers
./mmap-read /tmp/invalidfile 10
open error: No such file or directory

--------------------------------------------------

mmap-write.c

/* Mapped-memory example - Writer program
*/
#include
#include
#include
#include
#include
#include
#include
#include "mmap.h"

/* return a uniformly generated random number in the range [low,high]
*/
int random_range (unsigned const low, unsigned const high) {
unsigned const range = high - low + 1;
return low + (int) (((double) range) * rand () / (RAND_MAX + 1.0));
}

/* Create and write to a shared file for communication with another process.
*
* argv[1] = file name
*
* Note: Error processing is omitted
*/
int main (int argc, char* const argv[]) {
int fd;
void* file_memory;

/* seed the random number generator */
srand (time (NULL));

/* open or create a file to hold an unsigned integer */
fd = open (argv[1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);

/* write FILESIZE spaces */
for (int i=0; i write (fd, "", 1); /* write a NULL at EOF */

/* create the memory-mapping
1st param=start addr of mapping into memory, NULL means chosen by OS
2nd param=length of map (bytes)
3rd param=protection
4th param=options, MAP_SHARED used for interprocess communications
5th param=file descriptor of mapped file
6th param=offset from start of file where mapping starts
*/
file_memory = mmap (NULL, FILESIZE, PROT_WRITE, MAP_SHARED, fd, 0);
close (fd);

/* write a random integer to memory-mapped area */
sprintf((char*) file_memory, "%d ", random_range (-100, 100));

/* release the memory */
munmap (file_memory, FILESIZE);
}

--------------------------------------------------------------------

mmap-read.c

/* Mapped-memory example - Reader program
*/

#include
#include
#include
#include
#include
#include
#include "mmap.h"

int main (int argc, char* const argv[]) {
int fd;
void* file_memory;
int integer;

/* open the file */
fd = open (argv[1], O_RDWR, S_IRUSR | S_IWUSR);

/* create the memory-mapping */
file_memory = mmap (NULL, FILESIZE, PROT_READ | PROT_WRITE,
       MAP_SHARED, fd, 0);
close (fd);

/* read and print the integer */
sscanf (file_memory, "%d", &integer);
printf ("file contains: %d ", integer);

/* release the memory */
munmap (file_memory, FILESIZE);

return 0;
}

--------------------------------------------------------------------

mmap.h

/*(It has this line of code only)*/

#define FILESIZE 256

--------------------------------------------------------------------

Makefile

all: mmap-read.o mmap-write.o
   gcc -o mmap-read mmap-read.o
   gcc -o mmap-write mmap-write.o

mmap-read.o: mmap-read.c
   gcc -c mmap-read.c

mmap-write.o: mmap-write.c
   gcc -c mmap-write.c

clean:
   rm -f *.o mmap-read mmap-write *~

Explanation / Answer

mapwrite.c

#include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/mman.h> #include <unistd.h> int main(int argc, const char *argv[]) { const char *filepath = "/tmp/mmapped.bin"; int fd = open(filepath, O_RDONLY, (mode_t)0600); if (fd == -1) { perror("Error opening file for writing"); exit(EXIT_FAILURE); } struct stat fileInfo = {0}; if (fstat(fd, &fileInfo) == -1) { perror("Error getting the file size"); exit(EXIT_FAILURE); } if (fileInfo.st_size == 0) { fprintf(stderr, "Error: File is empty, nothing to do "); exit(EXIT_FAILURE); } printf("File size is %ji ", (intmax_t)fileInfo.st_size); char *map = mmap(0, fileInfo.st_size, PROT_READ, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { close(fd); perror("Error mmapping the file"); exit(EXIT_FAILURE); } for (off_t i = 0; i < fileInfo.st_size; i++) { printf("Found character %c at %ji ", map[i], (intmax_t)i); } if (munmap(map, fileInfo.st_size) == -1) { close(fd); perror("Error un-mmapping the file"); exit(EXIT_FAILURE); } close(fd); return 0; }