0

Program 1:

    #include<stdio.h>
    void main()
    {
        printf("Hello\n");
    }

Output:

    $strace ./a.out
    ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
    fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
    .
    .
    .
    .
    write(1, "Hello\n", 6Hello
    )                  = 6
    exit_group(6)                           = ?
    $

Program 2:

    #include<stdio.h>
    void main()
    {
        char buf[2];
        setbuf(stdout,buf);
        printf("Hello\n");
    }

Output:

    $ strace ./a.out 
    ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
    fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 3), ...}) = 0
    .
    .
    .
    .
    write(1, "Hello\n", 6Hello
    )                  = 6
    exit_group(6)                           = ?
    $

My requirement is to find the use of setbuf function. So, I experimented two programs which is showed above. In program 1, I didn't set the buffer to stdout. So, it uses the inbuilt buffer. The size of inbuilt buffer is 4096(Approximately). For that, Hello is enough for single write. So, write system call will be called only once.

But In program 2, I explicitly set the buffer with the size of 2 character. So, printf uses this buffer. So, my expected output is that the write system should be called for 3 to 4 times. But, the strace output for both of the programs are remain same.

So In program 2, the printf function uses the buffer(buf) are not. If it is used buf, then write system call will be called for 4 times. So, How to I check how many times my "a.out" program call write function.

mohangraj
  • 9,842
  • 19
  • 59
  • 94

1 Answers1

5

The problem is that setbuf() does not specify the size of the buffer, it is assumed to be BUFSIZ, not 2, because the function will never see that 2.

And since most likely BUFSIZ is greated than 2 you have a buffer overflow!

That's quite inconvenient, and that's why there is the new setvbuf():

int setvbuf(FILE *stream, char *buf, int mode, size_t size);

That will be used such as:

setvbuf(stdout, buf, _IOFBF, sizeof(buf));

PS: You should not write void main(), use int main() instead.

rodrigo
  • 94,151
  • 12
  • 143
  • 190
  • If I change the value of BUFSIZ macro to 2. Then? – mohangraj Sep 22 '15 at 15:18
  • I assume you'd have to recompile your stdlib for that. BUFSIZ comes from the headers for your standard library which communicate compile-time settings as far as the library is concerned. – Peter - Reinstate Monica Sep 22 '15 at 15:18
  • @mohan: No!, `BUFSIZ` is a predefined macro that tells you what buffer size the standard library expects. Changing the macro will not change the library (unless you recompile `libc`, and you don't want that). – rodrigo Sep 22 '15 at 15:20
  • So, How to Recompile the stdlib? – mohangraj Sep 22 '15 at 15:21
  • http://www.gnu.org/software/libc/manual/html_node/Configuring-and-compiling.html. But seriously, that's no simple task. What the assignmant may have meant (if you can only use setbuf() and not setvbuf()) is to set the buffer to null, effectively setting the mode to unbuffered. – Peter - Reinstate Monica Sep 22 '15 at 15:22
  • Is there any other way to experiment my program as I expect. – mohangraj Sep 22 '15 at 15:24
  • @mohan, what are you really after? Recompiling the standard library is quite a big deal. Why not just use `setvbuf()` instead of `setbuf()` if you want to explore the effect of having a small I/O buffer? – John Bollinger Sep 22 '15 at 15:25
  • @mohan, or if you insist on experimenting with `setbuf()` in particular, then that should probably be done in the context of [its documentation](http://pubs.opengroup.org/onlinepubs/009695399/functions/setbuf.html). – John Bollinger Sep 22 '15 at 15:27
  • @JohnBollinger For realtime purpose I would use setvbuf. But, I'd like to know the difference b/w these two. So far only I tried it. Its OK. Thank you – mohangraj Sep 22 '15 at 15:28
  • @mohan, the only difference between `setbuf()` and `setvbuf()` is that the former assumes default values for two of the parameters accepted by the latter. Again, read the docs. *`setbuf()`'s behavior is defined in terms of `setvbuf()`*. – John Bollinger Sep 22 '15 at 15:31
  • Perhaps one should add that documentation for library functions (and utilities, and shell-builtins etc.) can these days be found by simply googling "man function-name", e.g. "man setbuf". You probably get a similar result by opening a terminal and saying "man setbuf" there, but that is sometimes more cumbersome and harder to read and you didn't set up LESS as your pager and you didn't export LESS=-X so you cannot scroll up to re-read while you are typing... so just google man setbuf. – Peter - Reinstate Monica Sep 22 '15 at 15:39