Lab-10 covers mmap(2), a system call that maps a chunk of memory.
Review the manpages in /examples/a directory for help on this lab.
Low-level access to virtual memory (memory mapping) is the last IPC
service we will cover in this course. You can view the mapping for
a process in /proc/self/maps. See proc(5) for info on this file.
Mmap(2) grabs a chunk of memory from the page table of the process's virtual
memory space. If the memory is associated with a file (a file mapping),
reads and writes to the memory chunk are redirected
to the file. If the chunk of memory is not associated with a file
(an anonymous mapping) reads and writes are redirected to the virtual
memory swap file.
In this lab you will create a mapped and an unmapped.
Copy these files into your 3600/a/ directory:
$ umask 027 $ cd $ cd 3600/a $ cp /home/fac/gordon/public_html/3600/examples/a/maptest.c . $ cp /home/fac/gordon/public_html/3600/examples/a/mylab10.c . $ cp /home/fac/gordon/public_html/3600/examples/a/Makefile . $ cp /home/fac/gordon/public_html/3600/examples/a/article .Before coding read the comments in maptest.c. Compile and execute. Start coding only when you are comfortable with the concepts in the program.
$ cp maptest.c mylab10.cYou task is to modify mylab10.c to create a second mapping that is anonymous (not associated with a file). You will do a memcpy of the existing mapping to this second anonymous mapping. You will then open an output file and write the second mapping to the output file. Currently, mylab10.c creates a memory mapping that is attached to a file named article.
The functionality of this lab is essentially to read an input file and copy it to an output file with memory mappings on both files. This is something you may never do in a real program, but it will give you practice on creating and using a memory mapping. Details follow.
STEP 1. Use open(2) to open an output file for writing. Pass the filename in from the cmdline. Recall this *sample* open system call:
int outf = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666);STEP 2. Use mmap(2) to create an anonymous mapping the same size as infile. From mmap manpage:
MAP_ANONYMOUS The mapping is not backed by any file; its contents are initialized to zero. The fd and offset arguments are ignored; however, some implementations require fd to be -1 if MAP_ANONYMOUS is specified, and portable applications should ensure this.A *sample* mmap command to create the mapping is shown here:
dest = mmap(NULL, filesize, PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,-1,0); if (dest == MAP_FAILED) perror("mmap:");STEP 3. Use memcpy(3) to to copy the original mapping (memory to memory copy) to the new mapping. From the manpage on memcpy note that you need to include <string.h>.
void *memcpy(void *dest, const void *src, size_t n); copies n bytes from memory area src to memory area dest; the memory areas should not overlap. Returns a pointer to dest.STEP 4. Use write to copy the anonymous mapping to the output file (if you opened the file in append mode you will append the file). This is a *sample* write command. See write(2) manpage for more details.
write(outf, source, filesize); # source is char *ptr to the memmapSTEP 5. Remove the code that displays the article to the screen.
Sample runs:Clarification of this lab... Add a command-line argument to get an output file name. (see sample runs) If no command-line arguments are entered, display a Usage statement, and end the program. If <offset> or <length> are not entered on the command-line, display a Usage statement, but continue the program. Default the offset and length to reasonable values. Command-line arguments offset and length are optional for the user. If length is not entered on the command-line, but offset is, the length should be set to display from offset to end-of-file. The starting program already maps your input file to virtual memory with mmap. The fstat(2) function is used to get the input file length. Flow of this lab: 1. Update changes to your command-line arguments. 2. Open an output file. 3. Use mmap to map some anonymous memory. 4. Copy the input file's memory mapping to the anonymous memory. 5. Write from memory-map to memory-map with memcpy() function. 6. Write from Anonymous memory-map to file with write().
with no arguments...$ ./lab10 Usage: ./lab10 <infile> <outfile> <offset> <length>with file names...$ ./lab10 article log Usage: ./lab10 <infile> <outfile> <offset> <length> filesize : 2103 bytes pa_offset 0 pid: 1702765 pagesize: 4096 bytes 2103 bytes written to file.including offset and length...$ ./lab10 article log 1485 74 filesize : 2103 bytes pa_offset 0 pid: 1703613 pagesize: 4096 bytes 74 bytes written to file. $ cat log Linux distributions are dominant in the server and supercomputing sectors.secret test run...$ ./lab10 article log2 1134 46 $ cat log2 (the secret output will be here)another secret test run...$ ./lab10 article log3 718 14 $ cat log3 (the secret output will be here)using strace...$ strace -e trace=mmap ./lab10 article log 2>out Usage: ./lab10 <infile> <outfile> <offset> <length> filesize: 2088 bytes pa_offset 0 pid: 16448 pagesize: 4096 2088 bytes written to file. $ cat out mmap(NULL, 165587, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6606f5a000 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6606f58000 mmap(NULL, 132288, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6606f37000 mmap(0x7f6606f3d000, 61440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f6606f3d000 mmap(0x7f6606f4c000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f6606f4c000 mmap(0x7f6606f52000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a000) = 0x7f6606f52000 mmap(0x7f6606f54000, 13504, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6606f54000 mmap(NULL, 1832960, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f6606d77000 mmap(0x7f6606d99000, 1339392, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f6606d99000 mmap(0x7f6606ee0000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x169000) = 0x7f6606ee0000 mmap(0x7f6606f2d000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7f6606f2d000 mmap(0x7f6606f33000, 14336, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f6606f33000 mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6606d74000 mmap(NULL, 2088, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6606f82000 mmap(NULL, 2088, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0) = 0x7f6606f81000 +++ exited with 0 +++ $ md5sum article log 32b7b6ec5ae25a69c05c5dd75f8f51e2 article 32b7b6ec5ae25a69c05c5dd75f8f51e2 log
To be collected...
3600/a/mylab10.c 3600/a/Makefile