To be sure, this is an example rooted solely in explanation. It is
silly to operate a pipe like this in a single application. Further,
the program will continually read from and write to the pipe (you can
kill the process with Ctrl-C). Nonetheless, this example serves
a good purpose: it demonstrates event-driven programming and the utility
of a main loop multiplexing I/O. The natural extension of this program
would be to separate it into two processes, a consumer and a producer,
and actually communicate interprocess over the pipe. Add a handful of
other IO Channels, some GUI events, a few timers, and so on, to the main
loop, and you will have a real program!

Creating an IO Channel

There are two ways to create a new IO Channel. The easiest method creates
the IO Channel from an existing open file descriptor. The file descriptor
can map to any object, including sockets and pipes:

The second parameter specifies the mode with which to open the file:
one of r, w, r+, w+, a or a+. These values have the same
meaning as with fopen(). For example, in this code snippet,
we are asking to create a read-only IO Channel.

In our example program in Listing 1, we create two IO Channels using
g_io_channel_unix_new(), one for each end of the pipe.

The first parameter, gio, is the IO Channel we want to watch. The
second parameter is a mask of one or more conditions for which to
watch. The condition G_IO_IN is true when there is data to be
read without blocking. Other conditions are G_IO_OUT (data can
be written without blocking), G_IO_PRI (urgent data is available
to read), G_IO_ERR (an error occurred) and G_IO_HUP
(the connection was hung up). The third parameter is the callback function
that the Glib main loop will invoke when the event occurs.