开发者

Understanding behaviour of read() and write()

hi i am a student and just start learning low level c programming.i tried to understand read() and write() methods with this program.

#include <unistd.h>
#include <stdlib.h>
main()
{
    char *st;
    st=calloc(sizeof(char),2);//allocate memory for 2 char
    read(0,st,2);
    writ开发者_JS百科e(1,st,2);
}

i was expecting that it would give segmentation fault when i would try to input more than 2 input characters.but when i execute program and enter " asdf " after giving " as " as output it executes "df" command.

i want to know why it doesn't give segmentation fault when we assign more than 2 char to a string of size 2.and why is it executing rest(after 2 char)of input as command instead of giving it as output only?

also reading man page of read() i found read() should give EFAULT error,but it doesn't.

I am using linux.


Your read specifically states that it only wants two characters so that's all it gets. You are not putting any more characters into the st area so you won't get any segmentation violations.

As to why it's executing the df part, that doesn't actually happen on my immediate system since the program hangs around until ENTER is pressed, and it appears the program's I/O is absorbing the extra. But that immediate system is Cygwin - see update below for behaviour on a "real" UNIX box.

And you'll only get EFAULT if st is outside your address space or otherwise invalid. That's not the case here.


Update:

Trying this on Ubuntu 9, I see that the behaviour is identical to yours. When I supply the characters asls, the program outputs as then does a directory listing

That means your program is only reading the two characters and leaving the rest for the "next" program to read, which is the shell.

Just make sure you don't try entering:

asrm -rf /

(no, seriously, don't do that).


You ask read() to read no more than 2 characters (third parameters to read()) and so it overwrites no more than two characters in the buffer you supplied. That's why there's no reason for any erroneous behavior.


When you read(), you specify how many bytes you want. You won't get more than that unless your libc is broken, so you'll never write beyond the end of your buffer as long as your count is never greater than the size of your buffer. The extra bytes remain in the stream, and the next read() will get them. And if you don't have a next read() in your app, the process that spawned it (which would normally be the shell) may see them, since spawning a console app from the shell involves attaching the shell's input and output streams to the process. Whether the shell sees and gets the bytes depends partly on how much buffering is done behind the scenes by libc, and whether it can/does "unget" any buffered bytes on exit.


with read(0, st, 2); you read 2 chars from standard input. The rest of what you typed will not be accuired from the program, but will not be omitted, so the keystrokes are going back to the shell, from which your program started (which are df and enter).


Since you only read 2 character, there is no problem. the df characters are not consume by your program, so they stay in the terminal buffer, and are consumed by the shell :

  • your program runs
  • you type asdf\n
  • your program reads asand leaves df\n in the tty buffer
  • you write the content of the st buffer to stdout
  • your program stops
  • the shell reads df\n from input and executes df command.

Fun things to try :

  • strace your program, to trace the system call : strace -e read, write ./yourprogram
  • read(0, st, 5)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜