Applying C - Pipes
Written by Harry Fairhead   
Monday, 03 January 2022
Article Index
Applying C - Pipes
Anonymous Pipes

ACcover

Anonymous Pipes

As well as named pipes there are anonymous pipes, usually just referred to as a pipe, which only have file descriptors but otherwise work in the same way as named pipes. To create an anonymous pipe all you have to do is call the pipe function with a two-element array to receive two file descriptors:

int fd[2];
pipe(fd);

When pipe returns it has stored a read file descriptor in fd[0] and a write descriptor in fd[1]. These can be used immediately to read and write to the pipe - you don't need to open any files.

The only question is how does the reading and writing process get the file descriptors? The answer is that they have to be related - one has to be a child process of the other and hence it inherits open file descriptors. The usual way to implement pipes between processes is to first create the pipe and then use fork to create a child process. For more information on fork see Chapter 12. There are other ways of passing a file descriptor to another process. You could use shared memory or a shared file.

Anonymous pipes also work with threads and in this case there is no need to worry about passing file descriptors as threads share file descriptors. However in most cases it is simpler to allow threads to share global data structures than to make use of an anonymous pipe for interthread communication.

An Anonymous Pipe Example

A simple implementation of the reader/writer example using pipes is:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char** argv) {
    int value1 = 0x55555555;
    int value2;
    int fd[2];
    pipe(fd);
    if (fork() == 0) {
        close(fd[0]);
        for (;;) {
            value1 = ~value1;
            write(fd[1], &value1, 4);
            printf("W%X", value1);
            fflush(stdout);
            sleep(1);
        }
    } else {
        close(fd[1]);
        for (;;) {
            read(fd[0], &value2, 4);
            if ((value2 != 0x55555555) && 
(value2 != ~0x55555555)) { printf("%x\n", value2); } printf("R%X", value2); fflush(stdout); sleep(1); } } return (EXIT_SUCCESS); }

In this case we simply call pipe to get a read and a write descriptor. The fork creates a new process which is a complete copy of the program. The child code "knows" which one it is as fork returns 0 for it and not for the parent process. In this way the child process executes the if clause, i.e. the writer, and the parent executes the else clause, i.e. the reader.

This code omits all error checking and you need to take into account the need to deal with the possibility that the pipe or the fork might fail and that the reader or writer might close the pipe so stalling the other process.

Notice that both named and anonymous pipes can be used with processes or threads. In the case of anonymous pipes you would work in exactly the same way as for the fork example, but in this case sharing the same copy of the file descriptor array.

It is also worth mentioning that pipes are used to connect command line operations using the pipe symbol |. In this case stdout is connected using a pipe to stdin. The easiest way to use this mechanism in a program is to use the popen and pclose command. However, this isn't much used in low-level or systems programming.

In chapter but not in this extract:

  • File & Directory Operations
  • ioctl

Summary

  • If you think of a file as just a sequence or stream of bytes that can be read or written, then you have an idea that fits a great many sources and sinks of data.

  • This idea is so powerful that under Linux/Unix you can view almost all data as an example of a file.

  • C has a standard way of working with files – streams – and it provides a range of functions for working with file pointers such as fopen and fclose.

  • C files are buffered and this can cause unexpected behavior. Use fflush to make sure that buffers are written out.

  • Although not part of the C standard, file descriptors are part of Linux- and POSIX-compliant operating systems. They provide a lower-level, but OS-dependent, way of working with files.

  • File descriptor functions are similar to C file functions, but they don’t start with f and are simply open, close, read, write, and so on.

  • As C files are actually opened as file descriptors under POSIX operating systems, you can find the descriptor corresponding to a stream using fileno.

  • Files can be shared between processes.

  • The state of Linux/Unix file locking is not good, but you can lock a range of bytes within a file as long as you are aware of the problems.

  • A pipe is like a shared file but stored in memory. There are named and anonymous pipes.

  • There are a range of file and directory manipulation commands that allow you to do things like rename files.

Now available as a paperback or ebook from Amazon.

Applying C For The IoT With Linux

  1. C,IoT, POSIX & LINUX
  2. Kernel Mode, User Mode & Syscall
  3. Execution, Permissions & Systemd
    Extract Running Programs With Systemd
  4. Signals & Exceptions
    Extract  Signals
  5. Integer Arithmetic
    Extract: Basic Arithmetic As Bit Operations
  6. Fixed Point
    Extract: Simple Fixed Point Arithmetic
  7. Floating Point
  8. File Descriptors
    Extract: Simple File Descriptors 
    Extract: Pipes 
  9. The Pseudo-File System
    Extract: The Pseudo File System
    Extract: Memory Mapped Files ***NEW
  10. Graphics
    Extract: framebuffer
  11. Sockets
    Extract: Sockets The Client
    Extract: Socket Server
  12. Threading
    Extract:  Pthreads
    Extract:  Condition Variables
    Extract:  Deadline Scheduling
  13. Cores Atomics & Memory Management
    Extract: Applying C - Cores 
  14. Interupts & Polling
    Extract: Interrupts & Polling 
  15. Assembler
    Extract: Assembler

Also see the companion book: Fundamental C

<ASIN:1871962609>

<ASIN:1871962463>

<ASIN:1871962617>

<ASIN:1871962455>

Related Articles

Remote C/C++ Development With NetBeans

Raspberry Pi And The IoT In C

Getting Started With C/C++ On The Micro:bit

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


Explore SyncFusion's Blazor Playground
16/04/2024

Syncfusion has provided an in-browser environment where you can write, compile and run code that uses Blazor components and get it previewed live.



Falco On Track To Version 1.0.0
02/04/2024

Falco is a cloud native runtime security tool for the Linux operating system, designed to detect abnormal behavior and warn of potential security threats in real-time. Now it's about to release its fi [ ... ]


More News

raspberry pi books

 

Comments




or email your comment to: comments@i-programmer.info

 



Last Updated ( Monday, 03 January 2022 )