1 / 16

Chapter 6 UNIX Special Files

Chapter 6 UNIX Special Files. Source: Robbins and Robbins, UNIX Systems Programming, Prentice Hall, 2003. 6.1 Pipes. pipe() Function. The simplest mechanism in UNIX for interprocess communication is the unnamed pipe, which is represented by a special file

tadita
Télécharger la présentation

Chapter 6 UNIX Special Files

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 6UNIX Special Files Source: Robbins and Robbins, UNIX Systems Programming, Prentice Hall, 2003.

  2. 6.1 Pipes

  3. pipe() Function • The simplest mechanism in UNIX for interprocess communication is the unnamed pipe, which is represented by a special file • The pipe() function creates a communication buffer that the caller can access through the two-entry array parameter ( i.e., fileDescriptors[2] ) • The data written to fileDescriptors[1] can be then read from fileDescriptors[0] on a first-in-first-out basis#include <unistd.h>int pipe(int fileIDs[2]); // An array with two members • If successful, the function returns zero; otherwise, it returns –1 and sets errno

  4. pipe() Function (continued) • A pipe has no external or permanent name, so a program can access it only through its two descriptors • For this reason, a pipe can be used only by the process that created it and by descendants that inherit the descriptors by way of a fork() call • The pipe() function creates a unidirectional communication buffer • When a process calls read() on a pipe, the read() function returns immediately if the pipe is not empty • If the pipe is empty, the read() function blocks until something is written to the pipe, as long as some process has the pipe open for writing • On the other hand, if no process has the pipe open for writing, a read() call on an empty pipe returns zero, indicating end of file • Normally, a parent process uses one or more pipes to communicate with its children as shown on the next slide • A parent creates a pipe before calling fork() to create a child • The parent then writes a message to the pipe • The childreads a message from the pipe

  5. Example use of pipe() #include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #define BUFFER_SIZE 100 // ********************************************* int main(void) { char bufferIn[BUFFER_SIZE] = "empty"; char bufferOut[BUFFER_SIZE] = "empty"; int bytesIn; pid_t childPid; int fileDescriptors[2]; int status; bytesIn = strlen(bufferIn); status = pipe(fileDescriptors); if (status == -1) { perror("Failed to create the pipe"); return 1; } // End if (More on next slide)

  6. Example use of pipe()(continued) childPid = fork(); if (childPid == -1) { perror("Fork call failed"); return 1; } // End if if (childPid != 0) /* parent code */ { strcpy(bufferOut, "Hello, child"); write(fileDescriptors[1], bufferOut, strlen(bufferOut)+1); } else /* child code */ { bytesIn = read(fileDescriptors[0], bufferIn, BUFFER_SIZE); } fprintf(stderr, "PID: %5d bufferIn: {%.*s} bufferOut: {%s}\n", getpid(), bytesIn, bufferIn, bufferOut); sleep(1); return 0; } // End main

  7. Redirection and Pipes • Pipes can be combined with redirection in a command line to connect the standard output of one process to the standard input of another • The vertical bar ( | ) placed between two program names on the command line represents a pipe • As an example, the following shell commands use the sort filter utility in conjunction with the ls utility to output a directory listing sorted by sizeuxb2% ls –l >directory.txtuxb2% sort –n +4 < directory.txt(Note: The "-n" option means sort numerically; the “+4" option means to find the sort key by skipping over four fields) • An alternative approach for creating a sorted directory listing is to use a pipe, thereby eliminating the need for an intermediate filels –l | sort –n +4 • Below is another example using pipesps –ef | grep "user1" | sort

  8. 6.3 FIFOs

  9. FIFOs • Pipes are temporary in the sense that they cease to exist when no process has them open • FIFOs or named pipes, are special files that persist even after all processes have closed them • A FIFO has a name and permissions just like an ordinary file and appears in a directory listing • Any process with the appropriate permissions can access a FIFO • A user creates a FIFO by executing the mkfifo command from a command shell or by calling the mkfifo() function from within a program

  10. mkfifo() Function • The mkfifo() function creates a new FIFO special file corresponding to the path name specified in the path parameter#include <sys/stat.h>int mkfifo(const char *path, mode_t mode); • The mode parameter specifies the permissions for the newly created FIFO • If successful, the function returns zero; otherwise, it returns –1 and sets errno • A return value of –1 means that the FIFO was not created • The following code segment creates a FIFO in the current working directory#define FIFO_PERMISSIONS (S_IRUSR | S_IWUSR)int status;status = mkfifo("client.fifo", FIFO_PERMISSIONS);if (status == -1) perror("Failed to create FIFO"); • The following code segment deletes the FIFO from the current working directoryint status;status = unlink("client.fifo");if (status == -1) perror("Failed to unlink FIFO");

  11. 6.4 Simple Client/Server Model

  12. Simple Client/Server Model • The client/server model is a standard pattern for process interaction • One simple implementation approach is through the use of FIFOs • One type of client/server communication is simple-request, where the client sends information to the server in a one-way transmission through the FIFO • Another type of client/server communication is request-reply, where the client sends a request to the server through the FIFO and the server sends a reply back through the FIFO • The following set of slides shows the implementation of the simple-request communication approach • The server creates the FIFO and opens it for both reading and writing • When an attempt is made to open a FIFO for only reading, the open() call blocks until another process opens the FIFO for writing • Because the server opens the FIFO for both reading and writing, the open() call does not block • The client opens the FIFO for writing, sends a message to the server, and closes its connection to the FIFO • The server reads the message from the FIFO, displays the message, and closes its connection to the FIFO

  13. Example of Server use of FIFO #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/stat.h> #define BUFFER_SIZE 100 // ********************************************* int main (int argc, char *argv[]) { int fifoDescriptor; char buffer[BUFFER_SIZE]; int status; int byteCount; if (argc != 2) { fprintf(stderr, "Usage: a.out fifo_name\n"); return 1; } (More on next slide)

  14. Example of Server use of FIFO (continued) status = mkfifo(argv[1], (S_IRUSR | S_IWUSR | S_IWGRP | S_IWOTH) ); if (status == -1) { perror("Server failed to create a FIFO"); return 1; } fifoDescriptor = open(argv[1], O_RDWR); if (fifoDescriptor == -1) { perror("Server failed to open its FIFO"); return 1; } byteCount = read(fifoDescriptor, buffer, BUFFER_SIZE); if (byteCount <= 0) perror("Problem occurred when server tried reading the FIFO"); fprintf(stderr, "SERVER RECEIVED: %.*s\n", byteCount, buffer); close(fifoDescriptor); return 1; } // End main

  15. Example of Client use of FIFO #include <errno.h> #include <fcntl.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <unistd.h> #include <sys/stat.h> #define BUFFER_SIZE 100 // *********************************** int main (int argc, char *argv[]) { time_t currentTime; char buffer[BUFFER_SIZE]; int fifoDescriptor; int byteCount; int bufferLength; if (argc != 2) { fprintf(stderr, "Usage: a.out fifo_name\n"); return 1; } (More on next slide)

  16. Example of Client use of FIFO (continued) fifoDescriptor = open(argv[1], O_WRONLY); if (fifoDescriptor == -1) { perror("Client failed to open FIFO for writing"); return 1; } currentTime = time(NULL); snprintf(buffer, BUFFER_SIZE, "%d: %s", getpid(), ctime(&currentTime)); bufferLength = strlen(buffer); byteCount = write(fifoDescriptor, buffer, bufferLength); if (byteCount != bufferLength) { perror("Client failed to write to FIFO"); return 1; } else fprintf(stderr, "\nClient sent a message to the server\n"); close(fifoDescriptor); return 0; } // End main 

More Related