atom
atom

Reputation: 375

Create a scenario where write() is blocking

I got this simple C program:

#include <stdio.h>

int main (int argc, char *argv[])
{
  printf ("Hello, world\n");

  return 0;
}

If I strace the compiled program printf() becomes write():

$ strace ./hw > x
execve("./hw", ["./hw"], [/* 19 vars */]) = 0
...
write(1, "Hello, world\n", 13)          = 13
...

My Question is the following: I want the OS blocking the program execution once it executes the write() call. Is it possible, as a simple non-root user, to create such a scenario? Note that I can not change anything to the program code.

My gut feeling tells me it should, but yet I was unable to find a solution. Imagine write() would write to a file descriptor reffering to an unbuffered character device. Such a device, wouldn't it force write() to block?

Upvotes: 2

Views: 340

Answers (2)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136505

If you write into a pipe and no one reads that pipe it eventually fills up. I may be wrong, the default Linux pipe size is 64KB.

Try piping the output of your application into an application that never reads its standard input, something like this:

./hw | sleep 1000

sleep never reads its standard input, this way you will be able to fill the pipe easily.

Upvotes: 1

rici
rici

Reputation: 241911

The write system call copies the data into a kernel buffer associated with the file descriptor. As long as it is possible to buffer, the call will not block. But if you write enough data to a slow output device, then eventually write will block.

It's a bit of work to get the write of a few bytes to block. Here's one way to do it:

First, create a named pipe:

mkfifo /tmp/the_fifo

Any attempt to open /tmp/the_fifo for writing will block until some process opens the fifo for reading. You can open the fifo for reading without reading anything with something like:

sleep 1000 < /tmp/the_fifo &

Now you can fill the fifo buffer:

yes > /tmp/the_fifo &

At this point, your program should block when it tries to write to /tmp/fifo.

When you're done, don't forget to kill the background processes and delete the named pipe.

Upvotes: 6

Related Questions