Thread: Reading a line from mapped memory

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    24

    Question Reading a line from mapped memory

    Hi,

    I need to read input from an mmap()'ed file one line at a time. But all the examples I've seen of memory mapping use mmap/memcpy to copy an entire file. Like:

    source = mmap(blah, blah...);
    destinaton = mmap(blah, blah...);
    memcpy(destination, source, ...);

    How would I just get one line from the source file? Is it possible to just specify the size of one line (they are all a fixed length, say 10 chars + a newline character) as an argument to mmap()? If so, can I do this in a loop, where the position of the pointer is where it left off during the last read (like when reading a regular file)?

    Thanks.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Try it and find out. mmap returns a void pointer, and as such, you're able to do whatever you want with it. Whether or not it works, however, is another story.

    I haven't tried, but theoreticly it looks like it should work with strncpy or what not. That's basicly what memcpy does anyway. It just copies N bytes, as opposed to stopping on null.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    24
    So why did you mmap it in the first place?
    I agree, it seems pointless to mmap the file for this purpose. However, the assignment requires I use it.

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    24
    Excellent! This pretty much does the trick. There is one little probelm though. I need to write that line to another mapped output file after being modified. I've modified the code above with the following:

    Code:
     int fd2 = open("out", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
    
     char * temp = (char *) malloc(128);
    
    char * dest = mmap(0, s.st_size*2, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd2, 0);
      if (dest == MAP_FAILED) {
        perror("mmap dest");
        exit(1);
      } //size*2 just to be safe
    .
    .
    .
      while( getline( p, &get ) != 0 ) {
        temp = get.bufp;   
         temp = strcat(temp, " foo bar\n");
        memcpy(dest, temp, sizeof(temp));
        printf( "temp = %s", temp );
         }
    .
    .
    .

  5. #5
    Registered User
    Join Date
    Oct 2001
    Posts
    24
    Okay...I hit enter by accident so I just posted half a message. That was what I added/changed to the code. However whe nI run it, I get a bus error. If I comment out the memcpy line, then it prints what it should to the screen.

    I've tried using different ombinations of size values (128, 80) and source poiters (the second argument - buf, p, get.bufp) but each time I get the same bus error. Does anyone know what's wrong with my memcpy that could be casuing it?

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    24
    I forgot that you have to write a null string at the end of the file.

    Code:
     if (lseek(fd2, s.st_size * 2, SEEK_SET) == -1){
        perror("lseek");
        exit(1);
      }
    
      if (write(fd2, "", 1) != 1) {
        fprintf(stderr, "write error\n");
        exit(1);
      }
    That fixed the bus error, but now, when I run it, I get garbled output in the file. Again, I think it has something to do with the size settings, but don't know how. Does anybody have any ideas?

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    24
    > There is one little probelm though. I need to write that line to
    > another mapped output file after being modified.

    I'm not going to complete your assignment, not because it's yours and you are supposed to learn from it, but because I don't feel like.
    Sorry, that came out wrong. I never meant to imply that the problem was with YOUR code, which was a big help, nor that you should do the assignment for me (nor would I want to), but rather just that there is another point where I'm stuck.

    All you need is another offset for the second map, which you increase with the number of bytes in the copied line at each iteration. That's straight-forward to code because my getline( ) function already returns this number (you could use strlen( ) otherwise anyway).
    True. The way I was going about this was kinda like looking for the easy way out. I could just write another routine that mirrors getline() except that it writes the line.

    I don't know why your code gets a bus error, because you didn't post what you assign to get.bufp.

    Thanks for your help
    Inisde getline(), get.bufp gets set to the line that was read.

  8. #8
    Registered User
    Join Date
    Oct 2001
    Posts
    24
    I think this is a little bloated. All you need to do before the getline( )-loop is int offset = 0;. And within the loop you write get.bufp = dest + offset; before you call getline, nul-terminate dest[offset + return_value_of_getline] and append your text. And then you increase offset with return_value_of_getline + length_of_your_text
    Okay, I think I follow this logic. Here's the code I got from the above

    Code:
    offset = 0; // new variable 
    while ((ret = getline(p, &get)) != 0) {
         get.bufp = dest + offest;
         dest[offset + ret] = '\0';
         dest = strcat(dest, "new text here\n");
         offset += (ret + strlen(dest));
    }

    Does that look like what you were trying to tell me?

    But I'm a little confused, shouldn't the first line after the while statement be reversed:

    dest = get.bufp + offset;

    And what would I memcpy() in this case and when....or do I even have to since dest is already a ptr to the mapped area of memory. I was thinking about copying get.bufp to a temp_ptr, then performing the operations (strcat, null-term) on that and using memcpy(dest, temp, strlen(temp)) to write to the file, but I'm not sure if it should be done inside the loop, once per iteration, or just wait until I amass one huge string and copy the whole thing once at the end.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-02-2009, 07:27 AM
  2. Reading random line from a text file
    By helloamuro in forum C Programming
    Replies: 24
    Last Post: 05-03-2008, 10:57 PM
  3. Reading particular memory location ?
    By realnapster in forum C Programming
    Replies: 15
    Last Post: 05-03-2006, 11:35 AM
  4. reading 3 ints from one line, then 3 from another
    By Tokay in forum C++ Programming
    Replies: 10
    Last Post: 11-13-2005, 09:42 PM
  5. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM