What is "complete error trapping"?

125 Views Asked by At

Write a program in C using only low-level I/O..

The program must have complete error trapping. In particular the program should use perror() to report system errors...

In my program...

test("checked argument count");


if((input_file1 = open(argv[1], O_RDONLY)) < 0)
{
    test("couldn't open file1");
    perror(argv[1]);
    close(input_file1);
    exit(1);
}
test("opened file1");

Would this be considered "complete error trapping" if I implement such code for every read/write attempt?

Note: test() is just for debugging and will be deleted later:

void test(const char * message)
{
    printf("\ttesting: %s \n", message);
}
1

There are 1 best solutions below

0
On

You shouldn't close the file descriptor that you failed to open.

Other than that, yes, you've done sufficient error checking on the open() call. Now repeat for the other open() calls, and the read() calls, and the write() calls, and presumably the close() calls that are part of the main-line processing — close() calls in the error paths are a best-effort and don't need to be error checked in the same way.

Your error reporting is not very helpful, though. You say 'file1' but that isn't the name of the file. Using perror() isn't going to help much there, either; I never use it because it doesn't give me enough control over the message format. You are passing the file name as the string; that's considerably better than people often do, but you can't also express which operation the program was attempting that failed. I'd use fprintf(stderr, ...) in conjunction with errno and strerror(). Be careful not to clobber errno by calling a function that itself sets errno (is your test() function safe?). If you aren't sure, capture errno and (if necessary) reset it to the captured value:

int errnum = errno;
test("couldn't open file", argv[1]);
errno = errnum;
perror(argv[1]);
exit(1);

The revised test() function might be:

#include <stdarg.h>
extern void test(char const *fmt, ...);
void test(char const *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    putc('\n', stderr);
}

That's the core of it; you'd need to adapt that to work with your current internals of the test() function. The declaration of test() with the ellipsis does not require the <stdarg.h> header; the implementation of test() does require the header.