could not understand the behavior of read system call
So this is the code I am trying to run:
#include<fcntl.h>
#include<stdio.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
int main(){
int ret;
ret = read(STDIN_FILENO,(int*)2000,3);
printf("%d--%s\n",ret,strerror(errno));
return 0;
}
and this is the output I get at the terminal
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ gcc test.c
anirudh@anirudh-Aspire-5920开发者_StackOverflow社区:~/Desktop/testing$ ./a.out
lls
-1--Bad address
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ ls
a.out htmlget_ori.c mysocket.cpp Packet Sniffer.c resolutionfinder.c test.c
anirudh@anirudh-Aspire-5920:~/Desktop/testing$
Question 1: When I type the address 2000 in th read call read(STDIN_FILENO,(int*)2000,3);
then where does the address lies. I think this is the absolute address of the RAM that I am trying to access. am I right or is it offset and is added to the Stack Segment Base Address. I do not know. The program is not giving me a SEGFAULT
for memory violation rather gives me Bad address
Question 2: Okay so the code crashes when I give the input as lls
and bash executes the "ls" part of that "lls". The reason is that the code crashes after reading the first "l" and the rest "ls" part is executed by bash. but why bash is executing the left "ls" part. Why is bash doing so because my code is crashed and even if bash was its parent process it should not read from the file-descriptor (STDIN_FILNO) opened by the code I wrote. ( I think so)...
Thanks for your time.
The 2000
that you are trying to use as an address is a process-specific virtual address. Chances are good that nothing is mapped into that range; you can add this code to see what your mappings currently are:
char cmd[20];
sprintf(cmd, "pmap -x %i", getpid());
printf("%s\n", cmd);
system(cmd);
If you really must gain access to system RAM around 2000
(and I can't imagine that you are), use the iopl(2)
system call to map that address range into your process memory space. And beware the consequences. :)
As for the rest of the ls
behaviour, try adding a \n
to your printf()
format string, I've found that not properly flushing output can lead to confusing-looking interaction, perhaps this is just confusing, rather than outright strange. :)
You are running on a CPU with paging. Your OS maintains page tables which translate from virtual to physical addresses. The page table for your process doesn't contain anything for virtual address 2000, so read()
notices, and returns -EFAULT
.
stdin
is connected to your terminal device (/dev/tty
). Your process inherits that terminal from your shell, and the shell gets it back on process exit.
精彩评论