graham glass and king ables unix for programmers and users third edition pearson prentice hall 2003 n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Chapter 13 Systems Programming PowerPoint Presentation
Download Presentation
Chapter 13 Systems Programming

Loading in 2 Seconds...

play fullscreen
1 / 160

Chapter 13 Systems Programming - PowerPoint PPT Presentation


  • 105 Views
  • Uploaded on

Graham Glass and King Ables, UNIX for Programmers and Users , Third Edition, Pearson Prentice Hall, 2003. Chapter 13 Systems Programming. Systems Programming. UNIX System calls: C functions that provide access to the file system, processes, and error handling.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

Chapter 13 Systems Programming


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
    Presentation Transcript
    1. Graham Glass and King Ables, UNIX for Programmers and Users, Third Edition, Pearson Prentice Hall, 2003. Chapter 13Systems Programming

    2. Systems Programming • UNIX System calls: C functions that provide access to the file system, processes, and error handling. • System Calls grouped into 3 main categories: • File Management (Fig. 13.1) • Process Management (Fig. 13.2)‏ • Error Handling (Fig. 13.3)‏

    3. Error Handling • Most system calls are capable of failing in some way. • Example: open a file may fail because file does not exist! • System call returns a value of -1 when it fails. • This value does not tell much about the cause of the failure.

    4. Each process has a global variable errno that holds the numeric code of the last system-call error. (Initially, it 0). “/usr/include/sys/errno.h” #define EPERM 1 /*Operation not permitted*/ #define ENOENT 2 /*No such file or directory*/ #define EIO 5 /* I/O error */ #define EMFILE 24 /* Too many open files */ #include <errno.h> Error Handling: errno

    5. Error Handling • function perror() describes the system-call error • void perror(char* str) • /* standard C function in stdio.h */ • Displays str followed by a description of the last system call error. • Error 0 is displayed if no error • errno should be manually reset to 0 after system call failure!

    6. errno = 2 Main: No such file or directory errno = 21 main: Is a directory errno = 29 main: Illegal seek main: Success Error Handling: perror() #include <stdio.h> #include <fcntl.h> #include <errno.h> void main() { int fd; fd = open ("nonexist.txt", O_RDONLY); if(fd == -1) { printf ("errno = %d\n", errno); perror("main"); } fd = open ("/", O_WRONLY); if(fd == -1) { printf ("errno = %d\n", errno); perror("main"); } fd = open ("nonexist.txt", O_RDONLY | O_CREAT, 0644); printf ("errno = %d\n", errno); perror("main"); errno = 0; perror("main"); }

    7. Unix files are organized by hierarchy of labels commonly known as directory structure. Regular files: sequence of bytes that generally corresponds to code or data. Directory files: stored in a special format and form the backbone of the file system (directory-specific system calls). Special files correspond to peripherals, such as printers, disks, pipes and sockets. Unix File System

    8. File Management • System Calls: open, fcntl, read, write, lseek, unlink, close • Typical sequence: • open • read/write • close

    9. Typical File I/O Sequence • int fd; • /* file descriptor 0: std. in, 1: std. out, 2: std error*/ • fd = open(fileName,...); • if (fd == -1) /* deal with error */ • fcntl(fd,...) /* set IO flags if necessary */ • read(fd,...) /* read from file */ • write(fd,...) /* write to file */ • lseek(fd,...) /* seek within file */ • close(fd); /* close file, freeing file descriptor */

    10. File Descriptors • Each descriptor has its own private set of properties • file pointer (stores offset within file; changes on read/write/lseek)‏ • flag indicating if the file descriptor should be closed or not when process execs • flag indicating if output to file should be appended to end of file or not • A pipe or a socket have additional properties

    11. File Descriptors • Can open file several times (with different descriptors)‏ • System calls open() and fcntl() both allow you to manipulate these flags. fd1 File fd2 fd3

    12. Opening a File: open()‏ • int open(char* fileName, int mode[, int perm]) • allows you to open an existing file or create a new file for r/w • fileName: absolute or relative path name • mode: bitwise or-ing of a r/w flag together with zero or more miscellaneous flags (next slide)‏ • permissions: supplied only when file is created (ex. 0600 octal)‏

    13. Mode Flags • r/w flags: O_RDONLY, O_WRONLY, O_RDWR • misc. flags: • O_APPEND : position file pointer at the end of file before each write • O_CREAT : if the file does not exist, create it and set the owner ID = process' effective UID (uses umask value to set permissions) • O_EXCL : if O_CREAT is set and file exists then open() fails • O_NONBLOCK: for named pipes • O_TRUNC: if file exists it is truncated to length 0

    14. Create a File #include <stdio.h> #include <fcntl.h> #include <errno.h> void main() { int tmpfd; char tmpName[32]; sprintf(tmpName, ".rev.%d", getpid()); tmpfd = open (tmpName, O_CREAT | O_RDWR, 0600); if(tmpfd == -1) { printf ("errno = %d\n", errno); perror("main"); } printf("create a file %s\n", tmpName); } create a file .rev.4024

    15. #include<fcntl.h> #include<stdio.h> #include<stdlib.h> void main(int argc,char *argv[]) { if (argc>1) { int fd = open (argv[1], O_RDONLY); if (fd == -1) { perror ("reverse: "); exit (1); } else printf("File %s opened \n", argv[1]); } } Opening an Existing File [c33225@snowball ~]$ ./fopen nonexist reverse: : No such file or directory [c33225@snowball ~]$ ./fopen power.h File power.h opened

    16. int creat(char* fileName, mode_t perm) <sys/stat.h> S_IRUSR: owner read permit S_IWUSR: owner write permit S_IXUSR: owner execute permit S_IRGRP: group read permit S_IWGRP: group write permit S_IROTH: others read permit S_IWOTH: owners write permit S_IXOTH: others execute permit open(“myfile”, O_CREAT, S_IRUSR | S_IXOTH) CREATING A FILE: CREAT()

    17. Read from a regular file: read()‏ • size_t read(intfd, void* buf, size_t count) • copies uptocount bytes from the file referenced by fd into buffer buf • the bytes are read from current position (file pointer) which is then updated accordingly

    18. Read from a regular file: read()‏ • it returns number of bytes copied • returns 0 if it attempts to copy after end of file • returns -1 if unsuccessful • Example: • charsRead = read(fd, buffer, BUFFER_SIZE); • if (charsRead == 0) break; • if (charsRead == -1) fatalError();

    19. int charsRead; char buffer [4096]; while (1) { charsRead = read (fd, buffer, 4096); if (charsRead == 0) { printf("reach the end of the file.\n"); break; /* EOF */ } if (charsRead == -1) { perror ("reverse: "); exit (1); } } Read Example [c33225@snowball ~]$ ./fread power.h File power.h opened reach the end of the file. [c33225@snowball ~]$ ./fread nonexist reverse: : No such file or directory

    20. Write to a regular file: write()‏ • ssize_t write(int fd, void *buf, size_t count)‏ • Copies upto count bytes from a buffer buf into the file referenced by fd • The bytes are written into current position (file pointer) which is then updated accordingly • If O_APPEND was set, file pointer is set to end of file before each write

    21. Write to a regular file:write()‏ • It returns number of bytes copied • You should check this return value • returns -1 if unsuccessful

    22. int charsRead, charsWritten; char buffer [4096]; while (1) { charsRead = read (fd, buffer, 4096); if (charsRead == 0) break; /* EOF */ if (charsRead == -1) { perror ("reverse: "); exit (1);} charsWritten=write(out,buffer,charsRead); if (charsWritten!=charsRead){ perror ("reverse: "); exit (1);} } } Write Example

    23. Moving the file pointer:lseek()‏ • off_tlseek(intfd, off_t offset, int mode) • Changes current file position in the file referenced by fd. • mode describes how to interpret the offset.

    24. Moving the file pointer:lseek() modes • mode = SEEK_SET • offset relative to start of file • mode = SEEK_CUR • offset relative to current position of file • mode = SEEK_END • offset relative to end of file

    25. Moving the file pointer:lseek()‏ • lseek fails if moved before start of file • returns new file position if successful • returns -1 if unsuccessful

    26. Assume, fd is a file descriptor, lines[] is an array that holds starting positions of each line in the file. for (i = 0; i <10; i++) { int charsRead; char buffer [4096]; lseek (fd, lines[i], SEEK_SET); charsRead = read (fd, buffer, lines[i+1] - lines[i]); write (1, buffer, charsRead); }

    27. Current Offset of lseek • To find out current position use: • currentOffset = lseek(fd, 0, SEEK_CUR); • If you move past the end of file and write there, Unix automatically extends the size of the file and treats intermediate area as NULLS (0)‏ • Unix does not allocate disk area for intermediate space!! • (see next example)‏

    28. [c33235@snowball ~]$ cat sparse.txt Sparsefile [c33235@snowball ~]$ cat normal.txt normalfile

    29. Closing a file: close()‏ • int close(intfd) • Frees fd; releases resources • When a process terminates, all fds are automatically closed • Still it is a good idea to close yourself • Returns • 0 if success • -1 if failure

    30. Deleting a file: unlink()‏ • int unlink(const char* fileName) • Removes the hard link from the fileName to its file • If fileName is the last hard link, file resources are deallocated. • Example: • unlink(tmpName);‏

    31. Reverse Example (reverse.c)‏ • Starting page 440 • % reverse -c fileName • Reverses all lines in fileName • The -c option reverses each line; • If fileName is missing, standard input is used

    32. Reverse Example Algorithm • Step 1: Parse Command Line (parseCommandLine, processOptions) • System Calls used: none • Step 2: If reading from standard input, create temp. file to store input; otherwise open file for input (pass1) • System Calls used: open()‏

    33. Reverse Example Algorithm • Step 3: Read from file in chunks storing starting offsets of each line in an array. If reading from std. input, write each chunk into temp. file. (pass1, trackLines) • System Calls used: read(), write()‏ • Step 4: Read input file again, but backward, copying each line to std. output; reverse the line if -c option (pass2, processLine, reverseLine) • System Calls used: lseek()‏

    34. Reverse Example Algorithm • Step 5: Close file; remove it if temp. file; (pass2) • System Calls used: close(), unlink()‏

    35. Listing of reverse.c #include <fcntl.h> /* For file mode definitions */ #include <stdio.h> #include <stdlib.h> /* Enumerator */ enum { FALSE, TRUE }; /* Standard false and true values */ enum { STDIN, STDOUT, STDERR }; /* Standard I/O channel indices */ /* #define Statements */ #define BUFFER_SIZE 4096 /* Copy buffer size */ #define NAME_SIZE 12 #define MAX_LINES 100000 /* Max lines in file */

    36. Listing of reverse.c /* Function Prototypes */ void parseCommandLine (int argc, char* argv[]); void processOptions (char* str); void usageError (); void pass1 (); void trackLines (char* buffer, int charsRead); void pass2 (); void processLine (int i); void reverseLine (char* buffer, int size); void fatalError ();

    37. Listing of reverse.c /* Globals */ char *fileName = NULL; /* Points to file name */ char tmpName [NAME_SIZE]; int charOption = FALSE; /* Set to true if -c option is used */ int standardInput = FALSE; /* Set to true if reading stdin */ int lineCount = 0; /* Total number of lines in input */ int lineStart [MAX_LINES]; /* Store offsets of each line */ int fileOffset = 0; /* Current position in input */ int fd; /* File descriptor of input */ /*****************************************************/

    38. Listing of reverse.c int main (int argc, char* argv[]) { parseCommandLine (argc,argv); /* Parse cmd line */ pass1 (); /* Perform first pass through input */ pass2 (); /* Perform second pass through input */ return (/* EXITSUCCESS */ 0); /* Done */ } /*****************************************************/

    39. Function parseCommandLine void parseCommandLine (int argc, char* argv[]) { /* Parse command line arguments */ int i; for (i= 1; i < argc; i++) { if(argv[i][0] == '-')‏ processOptions (argv[i]); else if (fileName == NULL)‏ fileName= argv[i]; else usageError (); /* An error occurred */ } standardInput = (fileName == NULL); }

    40. Function processOptions void processOptions (char* str) { /* Parse options */ int j; for (j= 1; str[j] != NULL; j++) { switch(str[j]) /* Switch on command line flag */ { case 'c': charOption = TRUE; break; default: usageError (); break; } } }

    41. Function usageError void usageError () { fprintf (stderr, "Usage: reverse -c [filename]\n"); exit (/* EXITFAILURE */ 1); }

    42. Function pass1 void pass1 () { /* Perform first scan through file */ int tmpfd, charsRead, charsWritten; char buffer [BUFFER_SIZE]; if (standardInput) /* Read from standard input */ { fd = STDIN; sprintf (tmpName, ".rev.%d",getpid ()); /* Random name */ /* Create temporary file to store copy of input */ tmpfd = open (tmpName, O_CREAT | O_RDWR, 0600); if (tmpfd == -1) fatalError (); } else /* Open named file for reading */ { fd = open (fileName, O_RDONLY); if (fd == -1) fatalError (); } lineStart[0] = 0; /* Offset of first line */ }

    43. Function pass1 Continued while (TRUE) /* Read all input */ { /* Fill buffer */ charsRead = read (fd, buffer, BUFFER_SIZE); if (charsRead == 0) break; /* EOF */ if (charsRead == -1) fatalError (); /* Error */ trackLines (buffer, charsRead); /* Process line */ /* Copy line to temporary file if reading stdin */ if (standardInput) { charsWritten = write (tmpfd, buffer, charsRead); if(charsWritten != charsRead) fatalError (); } } /* Store offset of trailing line, if present */ lineStart[lineCount + 1] = fileOffset; /* If reading standard input, prepare fd for pass2 */ if (standardInput) fd = tmpfd; }

    44. Function trackLines void trackLines (char* buffer, int charsRead) { /* Store offsets of each line start in buffer */ int i; for (i = 0; i < charsRead; i++) { ++fileOffset; /* Update current file position */ if (buffer[i] == '\n') lineStart[++lineCount] = fileOffset; } }

    45. Function pass2 void pass2 () { /* Scan input file again, displaying lines in reverse order */ int i; for (i = lineCount - 1; i >= 0; i--)‏ processLine (i); close (fd); /* Close input file */ if (standardInput) unlink (tmpName); /* Remove temp file that we made*/ }

    46. Function processLine void processLine (int i) { /* Read a line and display it */ int charsRead; char buffer [BUFFER_SIZE]; /* Find the line and read it */ lseek (fd, lineStart[i], SEEK_SET); charsRead = read (fd, buffer, lineStart[i+1] - lineStart[i]); /* Reverse line if -c option was selected */ if (charOption) reverseLine (buffer, charsRead); /* Write it to standard output */ write (1, buffer, charsRead); }

    47. Function reverseLine void reverseLine (char* buffer, int size) { /* Reverse all the characters in the buffer */ int start = 0, end = size - 1; char tmp; /* Leave trailing newline */ if (buffer[end] == '\n') --end; /* Swap characters in a pairwise fashion */ while (start < end) { tmp = buffer[start]; buffer[start] = buffer[end]; buffer[end] = tmp; ++start; /* Increment start index */ --end; /* Decrement end index */ } }

    48. Function fatalError void fatalError () { perror ("reverse: "); /* Describe error */ exit (1); }

    49. [c33225@snowball reverse]$ cat > test Christmas is coming, The days that grow shorter, Remind me of seasons I knew in the past. [c33225@snowball reverse]$ ./reverse test Remind me of seasons I knew in the past. The days that grow shorter, Christmas is coming, [c33225@snowball reverse]$ ./reverse -c test .tsap eht ni wenk I snosaes fo em dnimeR ,retrohs worg taht syad ehT ,gnimoc si samtsirhC [c33225@snowball reverse]$ cat test | ./reverse Remind me of seasons I knew in the past. The days that grow shorter, Christmas is coming,

    50. [c33225@snowball reverse]$ ./reverse hello world hi there hi there hello world [c33225@snowball reverse]$ ./reverse -c hi there hello world dlrow olleh ereht ih