1

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);
}
Community
  • 1
  • 1
  • Will ANYTHING throw an exception causing the program to crash? If you've managed to make this answer no, then it sounds like complete error trapping to me. – nhgrif Oct 29 '13 at 14:45
  • 7
    maybe you should ask your professor what he means. – AShelly Oct 29 '13 at 14:45
  • 3
    Regardless of my comments, I'm not the one grading your homework and @AShelly has a perfectly valid point. – nhgrif Oct 29 '13 at 14:48
  • 1
    I think "complete error trapping" in this case means "write normal code, not crap" (which implies checking return value of every system call which may fail). – hyde Oct 29 '13 at 14:49

1 Answers1

1

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278