CPS 356 & 444/544 Lecture notes: I/O Redirection, and Pipes and FIFOs



Coverage: [USP] §4.7 (pp. 128-132) and §§6.1-6.4 (pp. 183-202)


Implementing I/O redirection

redirecting stdout from the display to a disk file
  • open disk file
  • copy file descriptor for disk file into entry for stdout; use dup2, involves an implicit close on the target of the copy
  • close disk file using its file descriptor


(regenerated with minor modifications from [USP] Fig. 4.7, p. 131)




(regenerated with minor modifications from [USP] Fig. 4.6, p. 130)


Helpful functions

  • fileno(stdin): returns the file descriptor for stdin
  • dup(fileno(stdin)): returns a copy of its file descriptor argument
  • isatty(desc): returns 1 if file descriptor desc is an open descriptor connected to a terminal and 0 otherwise


Simple (unnamed) pipes

  • a process communication buffer
  • basic ingredient for interprocess communication (IPC) in UNIX
  • data written to filedes[1] can be read from filedes[0] using FIFO
  • created with pipe function
  • read blocks until something is written to the pipe
    • can be used as a synchronization mechanism
    • can be used to create a barrier
  • not very useful for a single process
  • only usable by a process which calls fork and its descendants


Setting up pipelines in C

  • grep cats pets > _text
  • wc -l < num_cats
  • grep cats pets | wc -l
  • ps -A | grep grep
  • traditionally, but perhaps non-intuitively, the command to the right of the pipe symbol (|) is the parent of that to the left of it in the command line
  • blocking nature of read and write synchronize the processes
  • use pipe and dup2 functions in concert to setup a pipeline


Implementing ls -l | sort -n +4

  • unifies many concepts we have learned
    • process creation and image swapping
    • low level I/O
    • interprocess communication
  • why return only error conditions?
  • graphical (octopus-looking) depiction of the changes to the file descriptor table before and after system calls

    • after call to fork



      (regenerated from [USP] Fig. 6.2, p. 191)

    • after both calls to dup2



      (regenerated from [USP] Fig. 6.3, p. 191)

    • after all calls to close



      (regenerated from [USP] Fig. 6.4, p. 192)


Named pipes (or FIFOs)

  • pipes are temporary, FIFOs are permanent (until you unlink)
  • useful when the processes communicating were not created with fork
  • created with mkfifo function call or UNIX command
  • resulting file contains p as the character to left of its file permission list in ls -l output
  • beauty of UNIX: unified file access interface
    • regular files
    • FIFOs
    • terminals
  • leads to a simple client-server model
  • note: data written to named pipes on our system is not line buffered;
    • must explicitly call fflush(stdout), or
    • use setvbuf to turn line buffering on


Note about pipes

  • writes to pipes are atomic (contrast with fprintf)
  • reads from pipes are not atomic


Observations on client-server programs

  • first version
    • simple-request: a one-way communication protocol; clients send information to server
    • why does server open pipe for writing, even though it will never write to it?
    • client cannot cause server to terminate
  • second version
    • request-reply: a two-way communication protocol
      • request pipe: client sends a request (`g')
      • sequence pipe: server sends a reply (sequence `#')
      • difficult to implement with only one named pipe
    • server replies (i.e., the sequence #) can be read by any client because of the single, shared pipe; side-effect of non-atomic reads
    • possible erroneous outcomes
      • partial input (e.g., read only 2 bytes)
      • complete, but incorrect, input due to the interleaving
    • quick fix: have client who read partial input send an error code (`e') to the server on the request pipe to cause it to terminate
      • causes all future clients to block
      • causes all pending clients to terminate (writing to an unopened pipe)
    • secure? absolutely not
      • a malicious client could intentionally bring down the server
      • moral of the story: a client should never have the capability to shut down the server
    • better solution: each client communicates to the server through its own individual named pipe


Experimental runs of client-server programs

  • one server, several clients (version one; [USP] exercise 6.12)
  • one server, two clients (version two; [USP] exercise 6.13)
  • two servers, one client (version two; [USP] exercise 6.14); it is possible that the client will get the same sequence # twice


References

    [USP] K.A. Robbins and S. Robbins. UNIX Systems Programming: Concurrency, Communication, and Threads. Prentice Hall, Upper Saddle River, NJ, Second edition, 2003.

Return Home