2.4 Library Function Calls

Team-FLY

We introduce most library functions by a condensed version of its specification, and you should always refer to the man pages for more complete information.

The summary starts with a brief description of the function and its parameters, followed by a SYNOPSIS box giving the required header files and the function prototype. (Unfortunately, some compilers do not give warning messages if the header files are missing, so be sure to use lint as described in Appendix A to detect these problems.) The SYNOPSIS box also names the POSIX standard that specifies the function. A description of the function return values and a discussion of how the function reports errors follows the SYNOPSIS box. Here is a typical summary.

The close function deallocates the file descriptor specified by fildes .

  SYNOPSIS  #include <unistd.h>    int close(int fildes);  POSIX  

If successful, close returns 0. If unsuccessful , close returns “1 and sets errno . The following table lists the mandatory errors for close .

errno

cause

EBADF

fildes is not valid

EINTR

close was interrupted by a signal

This book's summary descriptions generally include the mandatory errors. These are the errors that the standard requires that every implementation detect. We include these particular errors because they are a good indication of the major points of failure. You must handle all errors, not just the mandatory ones . POSIX often defines many other types of optional errors. If an implementation chooses to treat the specified condition as an error, then it should use the specified error value. Implementations are free to define other errors as well. When there is only one mandatory error, we describe it in a sentence . When the function has more than one mandatory error, we use a table like the one for close .

Traditional UNIX functions usually return “1 (or sometimes NULL ) and set errno to indicate the error. The POSIX standards committee decided that all new functions would not use errno and would instead directly return an error number as a function return value. We illustrate both ways of handling errors in examples throughout the text.

Example 2.4

The following code segment demonstrates how to call the close function.

 int fildes; if (close(fildes) == -1)    perror("Failed to close the file"); 

The code assumes that the unistd.h header file has been included in the source. In general, we do not show the header files for code segments.

The perror function outputs to standard error a message corresponding to the current value of errno . If s is not NULL , perror outputs the string (an array of characters terminated by a null character) pointed to by s and followed by a colon and a space. Then, perror outputs an error message corresponding to the current value of errno followed by a newline.

  SYNOPSIS  #include <stdio.h>    void perror(const char *s);  POSIX:CX  

No return values and no errors are defined for perror .

Example 2.5

The output produced by Example 2.4 might be as follows.

 Failed to close the file: invalid file descriptor 

The strerror function returns a pointer to the system error message corresponding to the error code errnum .

  SYNOPSIS  #include <string.h>    char *strerror(int errnum);  POSIX:CX  

If successful, strerror returns a pointer to the error string. No values are reserved for failure.

Use strerror to produce informative messages, or use it with functions that return error codes directly without setting errno .

Example 2.6

The following code segment uses strerror to output a more informative error message when close fails.

 int fildes; if (close(fildes) == -1)    fprintf(stderr, "Failed to close file descriptor %d: %s\n",                    fildes, strerror(errno)); 

The strerror function may change errno . You should save and restore errno if you need to use it again .

Example 2.7

The following code segment illustrates how to use strerror and still preserve the value of errno .

 int error; int fildes; if (close(fildes) == -1) {    error = errno;                           /* temporarily save errno */    fprintf(stderr, "Failed to close file descriptor %d: %s\n",                    fildes, strerror(errno));    errno = error;    /* restore errno after writing the error message */ } 

Correctly handing errno is a tricky business. Because its implementation may call other functions that set errno , a library function may change errno , even though the man page doesn't explicitly state that it does. Also, applications cannot change the string returned from strerror , but subsequent calls to either strerror or perror may overwrite this string.

Another common problem is that many library calls abort if the process is interrupted by a signal. Functions generally report this type of return with an error code of EINTR . For example, the close function may be interrupted by a signal. In this case, the error was not due to a problem with its execution but was a result of some external factor. Usually the program should not treat this interruption as an error but should restart the call.

Example 2.8

The following code segment restarts the close function if a signal occurs.

 int error; int fildes; while (((error = close(fildes)) == -1) && (errno == EINTR))  ; if (error == -1)    perror("Failed to close the file"); /* a real close error occurred */ 

The while loop of Example 2.8 has an empty statement clause. It simply calls close until it either executes successfully or encounters a real error. The problem of restarting library calls is so common that we provide a library of restarted calls with prototypes defined in restart.h . The functions are designated by a leading r_ prepended to the regular library name . For example, the restart library designates a restarted version of close by the name r_close .

Example 2.9

The following code segment illustrates how to use a version of close from the restart library.

 #include "restart.h"     /* user-defined library not part of standard */ int fildes; if (r_close(fildes) == -1)    perror("Failed to close the file"); /* a true close error occurred */ 
Team-FLY


Unix Systems Programming
UNIX Systems Programming: Communication, Concurrency and Threads
ISBN: 0130424110
EAN: 2147483647
Year: 2003
Pages: 274

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net