Problem about mmap()!

H

Hao Xu

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_TRUNC); 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,sizeof(people)*5,PROT_WRITE,MAP_SHARED,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("initialize 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;
}
 
F

Fredrik Tolf

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?

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
 
J

junky_fellow

Hao Xu said:
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_TRUNC); 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,sizeof(people)*5,PROT_WRITE,MAP_SHARED,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("initialize 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;
}

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.
 
E

Erik de Castro Lopo

Hao said:
Hi everyone!

I found that if you want to write to the memory got by mmap(),

Mmap() is not part of ISO standard C, so this question is
off topic here.
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?

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 (e-mail address removed) (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
 
C

CBFalconer

junky_fellow said:
.... snip ...

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.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,152
Members
46,697
Latest member
AugustNabo

Latest Threads

Top