Related
I have an MPI C program, and I need to get the output of an executable. The executable does a complicated calculation and outputs the results.
The output of the executable is something like this:
0.0225873863659866,0.0000000000000000,0.0000000000000000,
whithout a new line character at the end.
To execute and get the output of the command I tried:
double vals[3];
char command[256];
sprintf (command, "./a.out");
// Execute the command
FILE *cmd = popen(command, "r");
// Get the command output
char buf[256] = {0x0};
while (fgets(buf, sizeof(buf), cmd) != NULL) {
// Output is separated with ,
// separate the string
char *token = strtok(buf, ",");
for (int i = 0; i < 3; ++i) {
// store integral value
vals[i] = atof(token);
token = strtok(NULL, ",");
}
}
printf("vals = (%g, %g, %g) pid = %d \n", vals[0], vals[1], vals[2], pid);
// Close file
pclose(cmd);
In a serial test program, this works great. The problem is that with the MPI program, only PID 0 executes the command, and the rest of the processors don't do it. I also tried having each process call a different executable and different configurations of MPI_BARRIER, but nothing worked.
Why does this happen, and how can I fix it?
I am creating a program in C that splits a large text file into 10 segments, and then creates 10 threads with each thread generating a word count for each segment. I took the function word_count from this code: https://github.com/prateek-khatri/seaOfC/blob/master/frequencyMultiThread.c. That program works fine for me, but when I tried to use word_count in my own program, it crashes when trying to get the size of the buffer.
It seems like everything is ok in the function getCurrentSegmentWordcount, but when that function calls word_count, it crashes (segmentation fault) at the line printf("sizeof Buff: %d", sizeof(buff));.
#define _GNU_SOURCE
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#define NUMBER_OF_THREADS 10
//struct taken from reference:
struct return_val{
char wordlist[100][100]; //[chars][lines]
int count[100];
} *arr; //array of words
void *print_hello_world(void * tid)
{
//This function prints the thread’s identifier and then exits.
printf("Hello World. Greetings from thread %d\n", tid);
pthread_exit(NULL);
}
void *word_count(void* num)
{
int *ln = num;
unsigned int line_number = *ln;
//line_number++;
printf("Thread %d\n",line_number);
char cmd_p1[9] = "sed -n '\0";
char cmd_p2[2];
sprintf(cmd_p2,"%d",line_number); //stores string in buffer
char cmd_p3[21] = "p' 'maintainers.txt'\0";
char command[100];
command[0] = '\0';
//char * strcat ( char * destination, const char * source );
//appends a copy of source to destination
strcat(command,cmd_p1);
strcat(command,cmd_p2);
strcat(command,cmd_p3);
usleep(line_number);
char cmd[100] = " | tr [:space:] '\\n' | grep -v '^\\s*$' | sort | uniq -c | sort\0";
strcat(command,cmd);
printf("Command: %s\n",command);
//fflush(stdout);
FILE *in;
in= popen(command, "r"); //read command and pipe into the shell
rewind(in); //set file position to beginning of 'in'
char buff[50];
int counter = 0;
//char * fgets ( char * str, int num, FILE * stream );
//reads chars from stream and stores them as string into buff until all of buffer has been read
printf("before\n");
bool testBool = fgets(buff,sizeof(buff),in);
printf("testBool: %d\n", testBool);
//CRASH HAPPENS HERE:
//buff
printf("sizeof Buff: %d", sizeof(buff));
while(fgets(buff,sizeof(buff),in))
{
printf("fire 0.5");
char c=' ';
int i = 0;
int cnt = atoi(buff); //converts string to int.. buff == # of chars in file?
arr[line_number-1].count[counter] = cnt; //at this point line_number == 1
printf("fire1\n");
while(c!='\0')
{
c=buff[i];
buff[i]=buff[i+6];
i++;
}
int cnnt = 0;
while(c!=' ')
{
c = buff[cnnt];
cnnt++;
}
i=0;
while(c!='\0')
{
c=buff[i];
buff[i]=buff[i+cnnt];
i++;
}
sprintf(arr[line_number-1].wordlist[counter],"%s",buff);
printf("%d %s",arr[line_number-1].count[counter],arr[line_number-1].wordlist[counter]);
counter++;
}
printf("final count: %d", counter);
arr[line_number-1].count[counter] = -1;
fclose(in);
//pthread_exit(NULL); //didn't help to move here from getCurrentSegment...()
return NULL;
}
void *getCurrentSegmentWordcount(void * tid) { //declaring file pointer (value?)
int segment = tid;
segment = segment + 1; //converts to int
printf("segment/thread: %d \n", segment);
char text[1000];
//char buffer[150];
FILE *fp = fopen("words.txt", "r");
if(fp == NULL) {
printf("null file");
}
int i = 0;
long lSize;
char *buffer;
if( !fp ) perror("words.txt"),exit(1);
fseek( fp , 0L , SEEK_END);
lSize = ftell( fp );
rewind( fp );
buffer = calloc( 1, lSize+1 );
if( !buffer ) fclose(fp),fputs("memory alloc fails",stderr),exit(1);
if( 1!=fread( buffer , lSize, 1 , fp) )
fclose(fp),free(buffer),fputs("entire read fails",stderr),exit(1);
//printf(buffer);
char *token = strtok(buffer, "~");
if(segment == 1) {
printf("segment 1: %s", token);
word_count(&segment);
}
if(segment == 2) {
token = strtok(NULL,"~");
printf("segment 2: %s", token);
}
if(segment == 3) {
token = strtok(NULL,"~");
token = strtok(NULL,"~");
printf("segment 3: %s", token);
}
if(segment == 4) {
token = strtok(NULL,"~");
token = strtok(NULL,"~");
token = strtok(NULL,"~");
printf("segment 4: %s", token);
}
fclose(fp);
free(buffer);
//pthread_exit(NULL);//moving to end of word_count()
}
int main(int argc, char *argv[])
{
//The main program creates x threads and then exits.
pthread_t threads[NUMBER_OF_THREADS];
int status, i;
for(i=0; i < NUMBER_OF_THREADS; i++) {
printf("Main here. Creating thread %d\n", i+1);
status = pthread_create(&threads[i], NULL, getCurrentSegmentWordcount, (void * )i);
if (status != 0) {
printf("Oops. pthread create returned error code %d\n", status);
exit(-1);
}
}
sleep(8);
exit(NULL);
}
Output:
Main here. Creating thread 1
Main here. Creating thread 2
segment/thread: 1
Main here. Creating thread 3
segment 1: test(segment 1, handled my thread 1)
Thread 1
Main here. Creating thread 4
Command: sed -n '1p' 'maintainers.txt' | tr [:space:] '\n' | grep -v '^\s*$' | sort | uniq -c | sort
Main here. Creating thread 5
segment/thread: 2
before
segment/thread: 4
Main here. Creating thread 6
segment 4:
test test test test (segment 4, handled by thread 4)
Main here. Creating thread 7
segment 2:
test test (segment 2, handled by thread 2)
Main here. Creating thread 8
Main here. Creating thread 9
Main here. Creating thread 10
segment/thread: 3
segment 3:
test test test (segment 3, handled by thread 3)
segment/thread: 10
segment/thread: 9
segment/thread: 8
segment/thread: 5
segment/thread: 6
segment/thread: 7
testBool: 1
Makefile:20: recipe for target 'all' failed
make: *** [all] Segmentation fault (core dumped)
There are many issues with this code, some have been already mentioned by
user3629249, so I'll try to summarize the errors here.
Passing (void * )i for the argument for the thread is rather ugly. Sure it
works but this is for me sloppy programming, I'd declare an int array and fill
it with the id values and pass a pointer to the locations.
int ids[NUMBER_OF_THREADS];
for(i=0; i < NUMBER_OF_THREADS; i++) {
ids[i] = i+1;
status = pthread_create(&threads[i], NULL, getCurrentSegmentWordcount, ids + i);
...
}
and then in the thread function:
void *getCurrentSegmentWordcount(void * tid) { //declaring file pointer (value?)
int segment = *((int*) tid);
// segment = segment + 1; not needed anymore
...
}
This code is more clean, easier to understand for you and for the code reviewer,
does not relay on ugly unnecessary casts and is more portable.
Same thing with
void *print_hello_world(void *tid)
{
//This function prints the thread’s identifier and then exits.
printf("Hello World. Greetings from thread %d\n", tid);
pthread_exit(NULL);
}
This is uggly, you are trying to pass a pointer as an int. The size of a
pointer may not be the same as the size of an int. Using the same way of
passing a pointer to int (like for getCurrentSegmentWordcount):
void *print_hello_world(void *tid)
{
//This function prints the thread’s identifier and then exits.
printf("Hello World. Greetings from thread %d\n", *((int*) tid));
pthread_exit(NULL);
}
Write error messages to stderr. This FILE buffer is opened for that reason,
that's what people expect from programs to do. When you execute a program, you
can do this:
$ program 2>/tmp/error.log
or this
$ program 2>/dev/null | some_other_tool
so that you can separate the normal output from the error outputs.
And when a system function fails, the errno variable is set to the error code.
You can use perror for a standard error message or if you want a custom one,
use strerror:
pid_t p = fork();
if(p < 0)
{
perror("fork failed");
// or
fprintf(stderr, "Error while executing fork: %s\n", strerror(errno));
return; // or exit or whatever
}
You can write code in one line if you want to enter the C obfuscated contest,
otherwise don't do that. It's hard to read for you, it's hard to read for the
code reviewer/co-worker/superior. You gain nothing from it.
Instead of
if( !buffer ) fclose(fp),fputs("memory alloc fails",stderr),exit(1);
do
if(buffer == NULL)
{
fclose(fp);
fputs("memory alloc fails", stderr);
exit(EXIT_FAILURE); // or exit(your_exit_status)
}
It's easier to read for everyone.
You should always check the return value of functions that return a pointer.
Check the return value of malloc, calloc, realloc, strtok, etc.
if(segment == 2) {
token = strtok(NULL,"~");
printf("segment 2: %s", token);
}
If strtok returns NULL, then the printf line yields undefined behaviour.
See 3.5.3.3 comment 2:
3.5.3.3:
Synopsis
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
int printf_s(const char * restrict format, ...);
[...]
2 format shall not be a null pointer. The %n specifier (modified or not by flags, field width, or precision) shall not appear in the string pointed to by format. Any argument to printf_s corresponding to a %s specifier shall not be a null pointer.
[...]
4 The printf_s function is equivalent to the printf function except for the explicit runtime-constraints listed above.
Some libc implementation may forgive you to pass NULL to printf with %s
and print (null), but this is not portable and is undefined behaviour. So you
can only do the printf if token is not NULL.
The word_count function is a little bit horrible, specially how you construct
the commands.
char cmd_p1[9] = "sed -n '\0";
can be rewritten as
char cmd_p1[] = "sed -n '";
This will create a char array with the correct amount of bytes and initialize
it with a valid 0-terminated string, no need to add the '\0' yourself.
The commands that are the same, meaning that they don't need a value from a
variable can be store in a char[] or even in a const char*. Then construct
the whole thing with snprintf and sprintf, less lines, less mistakes:
void *word_count(void* num)
{
...
const char *pipe_cmd = "| tr [:space:] '\\n' | grep -v '^\\s*$' | sort | uniq -c | sort";
const char *format = "sed -n '%dp' 'maintainers.txt' %s";
int cmd_size = snprintf(NULL, 0, format, line_number, pipe_cmd);
char *command = malloc(cmd_size + 1);
if(command == NULL)
return NULL;
sprintf(command, format, line_number, pipe_cmd);
...
FILE *in;
in= popen(command, "r");
free(command);
...
}
Also note that
char cmd_p2[2];
sprintf(cmd_p2,"%d",line_number); //stores string in buffer
will overflow the buffer if the line number is greater than 9.
bool testBool = fgets(buff,sizeof(buff),in);
printf("testBool: %d\n", testBool);
fgets returns a pointer to char, not a bool. The printf will print the
value of a pointer as an integer. A pointer size is not necessarily the same as
an int size, in fact on my system a pointer is 8 bytes long, int is 4 bytes
long. You should do:
if(fgets(buff, sizeof(buff), in))
puts("fgets success");
//CRASH HAPPENS HERE:
//buff
printf("sizeof Buff: %d", sizeof(buff));
It won't crash because of the sizeof. sizeof is evaluated at compile time,
not at run-time.
The sizeof-operator returns a size_t.
%d is not the correct specifier for size_t, %lu is, it should be
printf("sizeof buff: %lu\n", sizeof buff);
It will most probably crash because of all the undefined behaviour before
this point.
arr[line_number-1].count[counter] = cnt;
In your whole code, arr is uninitialized, so you are accessing a value
through an uninitialized pointer. That's undefined behaviour and might lead to a
segfault.
I want to quote user3629249 here:
user3629249 wrote:
the main() function is starting several threads, then immediately exiting. The process of exiting also eliminates the threads Suggest: in main() calling pthread_join() for each thread. in the thread, at the end, call pthread_exit()
Please don't ignore compiler warnings, they are not there to annoy you, they are
there to help you. They are a hint that what you are doing may not be what you
really want. Undefined behaviour, segfaults etc. are often a consequence of
that. So heed warnings of the compiler and when you see one, look at your code,
try to understand it and fix it. If you don't understand the warning, you can
come here and ask a question about it. But having thousand of warning and
ignoring them will lead to headaches and quite franky a lot of wasted time on
your side and ours.
So, please fix all this warnings and details, look at the warning messages of
the compiler and the code might run without problems.
I'm trying to read information printed by program A from program B. How can I pass data from A to B using read()?.
code for A
#include <stdio.h>
int main(int argc, char **argv)
{
int i, j;
char instruc_list[11][3] = {"sa", "sb", "ss", "pa", "pb",
"ra", "rb", "rr", "rra", "rrb", "rrr"};
i = 0;
while (i < 11)
{
j = 0;
while (j < 3)
{
printf("%c", instruc_list[i][j]);
j++;
}
i++;
printf("\n");
}
return (0);
}
code for B
int main()
{
char buf[4];
while ((read(0,buf, 4)))
{
printf("%s", buf);
}
printf("\n");
return 0;
}
When I run this two programs, I get the following result.
Use the popen() and pclose() functions defined in stdio.h to pipe output between programs.
Here's an example program of how to print the output of the ls shell command in your program, taken from this link:
FILE *fp;
int status;
char path[PATH_MAX];
fp = popen("ls *", "r");
if (fp == NULL)
/* Handle error */;
while (fgets(path, PATH_MAX, fp) != NULL)
printf("%s", path);
status = pclose(fp);
if (status == -1) {
/* Error reported by pclose() */
...
} else {
/* Use macros described under wait() to inspect `status' in order
to determine success/failure of command executed by popen() */
...
}
For your case, you'd call popen("./A", "r");.
You can use popen() to read the output of program A from program B.
Compile the first program:
gcc a.c -o a
In the program B:
#include <stdio.h>
int main(void)
{
char buf[4];
FILE *fp;
fp = popen("./a", "r");
while( !feof(fp)) {
fscanf(fp, "%s", buf);
printf("%s\n", buf);
}
return 0;
pclose(fp);
}
Now compile and execute the program B:
gcc b.c -o b
me#linux:$ ./b
The output I got is:
sa
sb
ss
pa
pb
ra
rb
rr
rra
rrb
rrr
rrr
In program A, you're not writing the null terminators for the 3-letter strings... and in program B, you're not adding a null char after the characters you read (and haven't initialised buf, so it might not contain one). That's why you're getting garbage between the 3-letter strings you read... printf() is continuing past the characters you read because it hasn't found a null yet.
Also note that read() can return -1 for error, which would still test as true for your while loop. You should at least check that read() returns greater than 0 (rather than just non-zero), if not put in more thorough error handling.
So with some changes to address these issues, program B might become:
int main()
{
char buf[4];
int ret; // ** for the return from read()
while ((ret = read(0,buf, 4)) > 0) // ** read >0 (no error, and bytes read)
{
fwrite(buf, 1, ret, stdout); // ** write the number of chars
// you read to stdout
}
printf("\n");
return 0;
}
As for program A, right now it writes 3 characters for both the 2-letter and the 3-letter strings -- which means it includes the null char for the 2-letter strings but not for the 3-letter strings. With the changes to program B above, you don't need to write the null characters at all... so you could change:
while (j < 3)
to:
while (j < 3 && instruc_list[i][j] != 0)
to stop when the null character is reached (though it's still inefficient to use a printf() call just to write a single char -- perhaps putchar(instruc_list[i][j]); would be better). Or, you could just replace that inner while loop with:
fputs(instruc_list[i], stdout);
...which would then write the string in instruc_list[i] up to but not including the null char, and also change instruc_list[11][3] to instruc_list[11][4] so that it has room for the null char from the 3-letter string literals in the initialiser list.
I am writing the redirect function that writes the output of a command to a given filename.
For example:
echo Hello World > hello.txt would write 'Hello World' into hello.txt.
ls -al > file_list.txt would write the list of all file/directory names in the current directory into file_list.txt.
My function so far is defined as:
int my_redirect(char **args, int count) {
if (count == 0 || args[count + 1] == NULL) {
printf("The redirect function must follow a command and be followed by a target filename.\n");
return 1;
}
char *filename = args[count + 1];
//Concatenates each argument into a string separated by spaces to form the command
char *command = (char *) malloc(256);
for (int i = 0; i < (count); i++) {
if (i == 0) {
strcpy(command, args[i]);
strcat(command, " ");
}
else if (i == count - 1) {
strcat(command, args[i]);
}
else {
strcat(command, args[i]);
strcat(command, " ");
}
}
//command execution to file goes here
free(command);
return 1;
}
where args[count] is ">".
How can I execute the command given by the string from args[0] to args[count - 1] into the file given at args[count + 1]?
EDIT
These are the instructions we have been given:
"Improve your shell by adding a redirect for stdout to a file. Only attempt after completing Feature 1. Parse the line for >, take everything before as command, and the first word after as the filename (ignore <, >>, | etc).
Standard out is written out to file descriptor 1 (stdin is 0, stderr is 2). So this task can be achieved by opening the file, and copying it’s file descriptor over to 1 with dup2 system call.
int f = open( filename , O_WRONLY|O_CREAT|O_TRUNC, 0666) ;
dup2( f , 1 ) ;
Note: Using system call open not library wrapper fopen here."
If you are allowed to solve this problem in a special way, so it works only for a narrow range of problems, like capturing stdout of a command into a file, you can avoid reinventing the wheel using the popen() function from <stdio.h>.
Sketch of the program:
Determine output file name
Open output file for writing
Determine command and arguments
Construct the command string from the args up to the >.
Call FILE *cmd = popen(command, "r");
Read line from cmd stream, write to output file
Goto 6 while not EOF on the cmd stream.
pclose(cmd), fclose output stream
Do this only if your instructor does not expect you to use fork, dup, and friends.
For example, I code :
fp = popen("wc -l < myfile", "r");
But myfile should be any file's name which is parsed to this project. It could be file abc.txt or 123.txt or xy.txt etc.
Then I want to get the output of executing this wc -l < myfile. But the problem is that I don't know which function in C can help me to parse the name of the myfile to this shell command and I can also get the output.
Can anyone gives me some suggestions?
Edit:
The file I want to read is very large. I want to read its data into an array.I cannot use list to store it, because it is too slow to locate a specific data in list. The problem is that if I use one dimensional array to malloc() memory space to the array, there is no enough continuous memory space on the laptop. Therefore, I plan to use two dimensional array to store it. So I have to get the num of lines in the file and then decide the size of each dimensional in this array via log.
Thanks for all answers. This project is about reading two files. The first file is much larger than the second file. The second file is like:
1 13 0
2 414 1
3 10 0
4 223 1
5 2 0
The third num in each line is called "ID". For example, num "1" has ID 0, num "2" has ID 1, num "3" has ID "0". (Ignore the middle num in each line)
And the first file is like:
1 1217907
1 1217908
1 1517737
1 2
2 3
2 4
3 5
3 6
If each num in the first file has the ID "0", I should store the both of num in each line into an data structure array. For example, we can see that num "1" has ID "0" in second file, so I need to store:
1 1217907
1 1217908
1 1517737
1 2
from my first file into the data structure array. The num "2" has ID"1" but num "3" has ID "0" and num "4" has ID "1", so need to store : 2 3 but not store 2 4 from my first file. That's why I need use array to store the two files. If I use two arrays to store them, I can check whether this num's ID is "0" fast in the array belongs to second file because using array is fast to locate a specific data, the index can be the value of the num directly.
I think, you need to make use of snprintf() to generate the string to be passed to popen() first and then you can call popen() with that string.
Pseudo-code
char buf[32] = {0};
snprintf(buf, 32, "wc -l < %s", myfile);
fp = popen(buf, "r");
EDIT
To make it work for any length of myfile
int len = strlen(myfile) + strlen("wc -l < ") + 1;
char *buf = malloc(len);
snprintf(buf, len, "wc -l < %s", myfile);
fp = popen(buf, "r");
...
free(buf);
Note: As mentioned by Ed Heal in the comment, the 32 here is used here for just demo purpose. You should choose your temporary array length based on the length of the string held by myfile, plus the mandatory characters, plus null terminator, obviously.
If you're not going to do this yourself (without a shell), which you should, at least pass the filename in such a way that the shell will only ever interpret it as data rather than code to avoid potential for security incidents.
setenv("filename", "myfile"); /* put filename in the environment */
fp = popen("wc -l <\"$filename\"", "r"); /* check it from your shell script */
Forget popen - do it yourself
i.e.
FILE *f = fopen(argv[1], "r");
int lines = 0;
int ch;
while ((ch = fgetc(f)) != EOF) {
if (c == '\n') lines++;
}
EDIT - As the poster wants to load the whole file into memory
Add the checking for errors
FILE *f = fopen(argv[1], "r");
struct stat size;
fstat(fileno(f), &size);
char buf = malloc(size.st_size)
fread(buf, size.st_size, 1, f);
fclose(f);
All of the code below is untested. If I find time to test, I'll remove this caveat.
You can create your own wrapper to popen() to allow you to form an arbitrary command.
FILE * my_popen (const char *mode, const char *fmt, ...) {
va_list ap;
int result = 511;
for (;;) {
char buf[result+1];
va_start(ap, fmt);
result = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
if (result < 0) return NULL;
if (result < sizeof(buf)) return popen(buf, mode);
}
/* NOT REACHED */
return NULL;
}
Then, you can call it like this:
const char *filename = get_filename_from_input();
FILE *fp = my_popen("r", "%s < %s", "wc -l", filename);
if (fp) {
/* ... */
pclose(fp); /* make sure to call pclose() when you are done */
}
Here, we assume that get_filename_from_input() transforms the filename input string into something safe for the shell to consume.
It is rather complex (and error prone) to reliably fix up a filename into something the shell will treat safely. It is more safe to open the file yourself. However, after doing so, you can feed the file to a command, and then read out the resulting output. The problem is, you cannot use popen() to accomplish this, as standard popen() only supports unidirectional communication.†
†Some variations of popen() exist that support bidirectional communication.
FILE * my_cmd_open (const char *cmd) {
int s[2], p, status, e;
if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) < 0) return NULL;
switch (p = fork()) {
case -1: e = errno; close(s[0]); close(s[1]); errno = e; return NULL;
case 0: close(s[0]); dup2(s[1], 0); dup2(s[1], 1); dup2(s[1], 2);
switch (fork()) {
case -1: exit(EXIT_FAILURE);
case 0: execl("/bin/sh", "-sh", "-c", cmd, (void *)NULL);
exit(EXIT_FAILURE);
default: exit(0);
}
default: for (;;) {
if (waitpid(p, &status, 0) < 0 && errno == EINTR) continue;
if (WIFEXITED(status) && WEXITSTATUS(status) == 0) break;
close(s[0]); close(s[1]); errno = EPIPE;
return NULL;
}
}
close(s[1]);
return fdopen(s[0], "r+");
}
To efficiently read an entire file into memory, you can use mmap().
void * mmap_filename (const char *filename, size_t *sz) {
int fd = open(filename, O_RDONLY);
if (fd < 0) return NULL;
struct stat st;
if (fstat(fd, &st) < 0) {
close(fd);
return NULL;
}
*sz = st.st_size;
void *data = mmap(NULL, *sz, PROT_READ, MAP_PRIVATE, fd, 0);
close(fd);
return data != MAP_FAILED ? data : NULL;
}
Then, you can call it like this:
size_t sz;
void *data = mmap_filename(filename, &sz);
if (data) {
/* ... */
munmap(data, sz);
}
The example code above maps the entire file at once. However, the mmap() API allows you to map portions of the file from a particular offset into the file.