Question

Here is my code. I'm assuming this has something to do with improper use of pointers or maybe I'm not mapping and unmapping my memory correctly.

Could anyone please provide me with some insight into the issue?

#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <stdlib.h> 
#include <sys/mman.h>
#include <ftw.h>
#include <sys/stat.h>
#include <string.h>

int size;
int map1, map2;
void *tar, *temp;

int callback(const char *filename,
             const struct stat *sb2,
             int filetype,
             struct FTW *ftw)
{           
    printf("test");
    if(sb2->st_size == sb1->st_size){
        temp = mmap(NULL, sb2->st_size, PROT_NONE, 0, map2, 0);
        int cmp = memcmp(tar, temp, sb2->st_size);
        printf("%d\n", cmp);
        if(cmp == 0){
            printf("%s\n", filename);
        }  
        if(munmap(temp,sb2->st_size) == -1){
            fprintf(stderr, "Error in unmapping in callback function");
            exit(EXIT_FAILURE);
        }  
    }  

    return 0;   //continue to walk the tree
}  

int main(int argc, char *argv[])
{
    //check for correct arguments
    if (argc == 1 || argc > 3) {
        fprintf(stderr, "Syntax: %s filename dirname\n", argv[0]);
        exit(EXIT_FAILURE);
    }  


    //use stat to get size of filename
    struct stat sb1;
    if(stat(argv[1],&sb1) != 0){
        fprintf(stderr, "Error in stat().");
        exit(EXIT_FAILURE);
    }
    size = sb1.st_size;

    //fd = mmap filename
    tar = mmap(NULL,sb1->st_size, PROT_WRITE, MAP_SHARED, map1, 0);
    if(tar == 0){
        fprintf(stderr, "Main() mmap failed");
        exit(EXIT_FAILURE);
    }  


    //walk through the directory with callback function
    nftw(argv[2], callback, 20, 0);

    // use munmap to clear fd
    if (munmap(tar,sb1->st_size) == -1) {
        fprintf(stderr, "Error in unmapping");
        exit(EXIT_FAILURE);
    }  
}

EDIT

I now declare my struct stat sb1 right before I use the stat function. After doing that I receieved a segmentation error again. I then commented out my nftw() call and and printed out the size variable (which has a reasonable number so I believe that's working). The new error is:

Error in unmapping.

Was it helpful?

Solution

You declare:

struct stat *sb1;

You use:

stat(argv[1],sb1);

You crash and burn because sb1 is a null pointer (since the variable is defined at file scope, it is initialized with 0).

You need to declare (at file scope):

struct stat sb1;

And then in main() you can use:

if (stat(argv[1], &sb1) != 0)
    ...oops...

You'll have to review all uses of sb1 to fix the status change from pointer to object, adding an & where necessary, and changing -> to . where necessary.

mmap() by example

This is a mildly edited version of a function I wrote that uses mmap() to map a file into memory:

/* Map named file into memory and validate that it is a MSG file */
static int msg_mapfile(const char *file)
{
    int         fd;
    void       *vp;
    struct stat sb;

    if (file == 0)
        return(MSG_NOMSGFILE);
    if ((fd = open(file, O_RDONLY, 0)) < 0)
        return(MSG_OPENFAIL);
    if (fstat(fd, &sb) != 0)
    {
        close(fd);
        return(MSG_STATFAIL);
    }
    vp = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    close(fd);
    if (vp == MAP_FAILED)
        return(MSG_MMAPFAIL);

The MSG_xxxx constants are distinct error numbers applicable to the program it came from. It was only needing to read the file, hence the PROT_READ; I think you may be OK with that too.

OTHER TIPS

if (argc == 1 || argc > 3) {
    fprintf(stderr, "Syntax: %s filename dirname\n", argv[0]);
    exit(EXIT_FAILURE);
}

/* ... */

nftw(argv[2], callback, 20, 0);

I see a possibility for argv[2] to be NULL. Perhaps you meant:

if (argc != 3) {
    fprintf(stderr, "Syntax: %s filename dirname\n", argv[0]);
    exit(EXIT_FAILURE);
}

Which book are you reading?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top