Problem about mmap()!

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Hao Xu

    Problem about mmap()!

    Hi everyone!

    I found that if you want to write to the memory got by mmap(), you have
    to get the file descriptor for mmap() in O_RDWR mode. If you got the
    file descriptor in O_WRONLY mode, then writing to the memory got by
    mmap() will lead to segmentation fault. Anyone knows why? Is this a rule
    or a bug?

    What if I just want to write to the file and nothing else?

    Please, look at my tiny program, I wrote this to test mmap(), it is cute.

    #include <stdio.h>

    typedef struct{
    char name[4];
    int age;
    } people;

    int main(int argc, char** argv) {
    int fd, i;
    people *p_map;
    char temp;

    fd = open(argv[1], O_RDWR|O_TRUNC) ; //this works fine

    //fd = open(argv[1], O_WRONLY|O_TRUN C); this will cause segmentation fault

    if (fd == -1) {
    perror("open()" );
    }
    lseek(fd, sizeof(people)* 5-1, SEEK_SET);
    write(fd, " " , 1);

    p_map = (people *)mmap(NULL,siz eof(people)*5,P ROT_WRITE,MAP_S HARED,fd,0);
    close(fd);

    memset(p_map, '\0', sizeof(people)* 5);

    temp = 'b';
    for(i=0; i<5; i++) {
    temp++;
    //(p_map+i)->name = "aaa";
    //memcpy((p_map+i )->name, &temp, 2);
    memset((p_map+i )->name, temp, 3);
    (p_map+i)->age = 20+i;
    }
    printf("initial ize over\n");
    for(i=0; i<5; i++) {
    printf("%s\t%d\ n", (p_map+i)->name, (p_map+i)->age);
    }
    sleep(10);

    munmap(p_map, sizeof(people)* 5);
    printf( "umap ok\n" );

    return 0;
    }
  • Fredrik Tolf

    #2
    Re: Problem about mmap()!

    On Tue, 2004-08-24 at 09:52 +0800, Hao Xu wrote:[color=blue]
    > Hi everyone!
    >
    > I found that if you want to write to the memory got by mmap(), you have
    > to get the file descriptor for mmap() in O_RDWR mode. If you got the
    > file descriptor in O_WRONLY mode, then writing to the memory got by
    > mmap() will lead to segmentation fault. Anyone knows why? Is this a rule
    > or a bug?[/color]

    That is highly implementation-defined. You would probably be much more
    likely to get a sensible reply if you post to the newsgroup dealing with
    your operating system and/or hardware platform.

    Fredrik Tolf


    Comment

    • junky_fellow

      #3
      Re: Problem about mmap()!

      Hao Xu <traverser@vip. sina.com> wrote in message news:<cge70r$2j ik$1@mail.cn99. com>...[color=blue]
      > Hi everyone!
      >
      > I found that if you want to write to the memory got by mmap(), you have
      > to get the file descriptor for mmap() in O_RDWR mode. If you got the
      > file descriptor in O_WRONLY mode, then writing to the memory got by
      > mmap() will lead to segmentation fault. Anyone knows why? Is this a rule
      > or a bug?
      >
      > What if I just want to write to the file and nothing else?
      >
      > Please, look at my tiny program, I wrote this to test mmap(), it is cute.
      >
      > #include <stdio.h>
      >
      > typedef struct{
      > char name[4];
      > int age;
      > } people;
      >
      > int main(int argc, char** argv) {
      > int fd, i;
      > people *p_map;
      > char temp;
      >
      > fd = open(argv[1], O_RDWR|O_TRUNC) ; //this works fine
      >
      > //fd = open(argv[1], O_WRONLY|O_TRUN C); this will cause segmentation fault
      >
      > if (fd == -1) {
      > perror("open()" );
      > }
      > lseek(fd, sizeof(people)* 5-1, SEEK_SET);
      > write(fd, " " , 1);
      >
      > p_map = (people *)mmap(NULL,siz eof(people)*5,P ROT_WRITE,MAP_S HARED,fd,0);
      > close(fd);
      >
      > memset(p_map, '\0', sizeof(people)* 5);
      >
      > temp = 'b';
      > for(i=0; i<5; i++) {
      > temp++;
      > //(p_map+i)->name = "aaa";
      > //memcpy((p_map+i )->name, &temp, 2);
      > memset((p_map+i )->name, temp, 3);
      > (p_map+i)->age = 20+i;
      > }
      > printf("initial ize over\n");
      > for(i=0; i<5; i++) {
      > printf("%s\t%d\ n", (p_map+i)->name, (p_map+i)->age);
      > }
      > sleep(10);
      >
      > munmap(p_map, sizeof(people)* 5);
      > printf( "umap ok\n" );
      >
      > return 0;
      > }[/color]

      on UNIX/LINUX machine your mmap system call will fail if you open the
      file
      in O_WRONLY mode and try to map that file with PROT_WRITE set for
      MAP_SHARED
      mapping. See the man page of mmap.
      so you are trying to write at some invalid address, thats why SIGSEGV.

      i would advise you that after every system call, you *must* always
      check whether your system call was successful or not.

      Comment

      • Erik de Castro Lopo

        #4
        Re: Problem about mmap()!

        Hao Xu wrote:[color=blue]
        >
        > Hi everyone!
        >
        > I found that if you want to write to the memory got by mmap(),[/color]

        Mmap() is not part of ISO standard C, so this question is
        off topic here.
        [color=blue]
        > you have
        > to get the file descriptor for mmap() in O_RDWR mode. If you got the
        > file descriptor in O_WRONLY mode, then writing to the memory got by
        > mmap() will lead to segmentation fault. Anyone knows why? Is this a rule
        > or a bug?[/color]

        If you open the file write only and then read from it, I
        would expect that it should not work. How it "doesn't
        work" is probably unspecified and a segfault is not an
        unreasonable version of "doesn't work".

        Erik
        --
        +-----------------------------------------------------------+
        Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid)
        +-----------------------------------------------------------+
        `If you want a vision of the future, it is a wireless broadband
        network feeding requests for foreign money-laundering assistance
        into a human temporal lobe, forever. With banner ads.'
        -- John M. Ford

        Comment

        • CBFalconer

          #5
          Re: Problem about mmap()!

          junky_fellow wrote:[color=blue]
          > Hao Xu <traverser@vip. sina.com> wrote:[color=green]
          >>
          >> I found that if you want to write to the memory got by mmap(),
          >> you have to get the file descriptor for mmap() in O_RDWR mode.
          >> If you got the file descriptor in O_WRONLY mode, then writing
          >> to the memory got by mmap() will lead to segmentation fault.
          >> Anyone knows why? Is this a rule or a bug?
          >>[/color][/color]
          .... snip ...[color=blue]
          >
          > on UNIX/LINUX machine your mmap system call will fail if you open
          > the file in O_WRONLY mode and try to map that file with PROT_WRITE
          > set for MAP_SHARED mapping. See the man page of mmap. so you are
          > trying to write at some invalid address, thats why SIGSEGV.
          >
          > i would advise you that after every system call, you *must* always
          > check whether your system call was successful or not.[/color]

          Please don't answer off-topic questions here other than to
          redirect them to an appropriate newsgroup. Especially don't
          answer them with more off-topic data, which won't be properly
          evaluated because the knowledgeable people aren't here.

          --
          Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
          Available for consulting/temporary embedded and systems.
          <http://cbfalconer.home .att.net> USE worldnet address!


          Comment

          Working...