#include "lrqElib.h" #include "lrqEdefs.h" #include #include #include #include #ifdef lrqEopen # undef lrqEopen #endif #undef open static char lrqEo_buf[1500]; /* for the "why" */ #define buf lrqEo_buf #include int lrqEopen(const char *filename, int whatfor, ...) { va_list ap; int creatmode = 0; int fd; int savsyserrno; char *otext, *mtext, *special; int ewhat; int writing = 0; char *what = "file"; /* file/fifo/device/directory */ char *reason; if (whatfor & O_CREAT) { va_start(ap, whatfor); creatmode = va_arg(ap, int); va_end(ap); } errno = 0; if ((fd = open(filename, whatfor, creatmode)) >= 0) { return fd; } /* we have an error */ /* Save the original error message */ savsyserrno = errno; if (filename == (char *) 0) { lrqE_error(lrqE_EPROG, "read: called with null file name"); return -1; } else if (errno == EFAULT) { ewhat = lrqE_EPROG; filename = "[corrupted filename]"; } /** * can't %s \"%s\" for %s %s because %s * otext file mtext special reason */ /* Make a description of what we tried to do.. */ if (whatfor & O_CREAT) { otext = "create"; } else { if (whatfor & O_TRUNC) { otext = "open (truncate)"; } else { otext = "open"; } } if (whatfor & O_RDWR) { mtext = "update"; writing = 1; } else if (whatfor & O_WRONLY) { mtext = "writing"; writing = 1; } else { mtext = "reading"; } if (whatfor & O_EXCL) { special = "(for exclusive access) -- \n\t"; } else { special = "-- "; } /** Try to figure out the problem... **/ /* Some special cases: */ switch (savsyserrno) { case EAGAIN: reason = "it already exists, and there are outstanding locks (EAGAIN)"; ewhat = lrqE_EFATAL; break; case EEXIST: reason = "it already exists"; ewhat = lrqE_EFATAL; break; case EFAULT: reason = "the filename was corrupt [EFAULT]"; ewhat = lrqE_EFATAL; break; case EINTR: /* See if we can do it again this time! */ if ((fd = open(filename, whatfor, creatmode)) >= 0) { return fd; } reason = "a signal interrupted the system call."; ewhat = lrqE_EFATAL; break; case EIO: reason = "there was a hangup or STREAMS error"; ewhat = lrqE_EFATAL; break; case EISDIR: reason = "can't alter directories"; ewhat = lrqE_EFATAL; what = "directory"; break; case EMFILE: reason = "too many files are already open"; ewhat = lrqE_EFATAL; break; #ifdef EMULTIHOP case EMULTIHOP: reason = "MULTIHOP bug in RFS; use NFS instead!"; ewhat = lrqE_EFATAL; what = "remote file"; break; #endif case ENFILE: reason = "the system file table is full"; ewhat = lrqE_EFATAL; break; case ENOENT: if (whatfor & O_CREAT) { reason = "a directory in the path doesn't exist"; } else { reason = "it doesn't exist"; } ewhat = lrqE_EFATAL; break; #ifdef ENOLINK case ENOLINK: reason = "the remote machine it's is now unavailable"; ewhat = lrqE_EFATAL; what = "remote file"; break; #endif case ENOMEM: reason = "the system has run out of memory [ENOMEM]"; ewhat = lrqE_EFATAL; break; case ENOSPC: reason = "the file system has run out of i-nodes"; ewhat = lrqE_EFATAL; break; #ifdef ENOSR case ENOSR: reason = "no streams are available"; ewhat = lrqE_EFATAL; what = "streams device"; break; #endif case ENOTDIR: /*NOTDONE: find out which! */ { extern char *lrqEcheckpath(); char *d = lrqEcheckpath(filename, "d"); if (d != (char *) 0) { reason = d; } else { reason = "one of the path compnents isn't a directory."; } ewhat = lrqE_EFATAL; } break; case ENXIO: what = "special device"; ewhat = lrqE_EFATAL; reason = "no kernel driver, or polluted stream [ENXIO]"; break; case EROFS: reason = "the file system is mounted read-only"; ewhat = lrqE_EFATAL; break; case ETXTBSY: what = "program text"; reason = "the program is currently running"; ewhat = lrqE_EFATAL; break; default: if (savsyserrno < sys_nerr) { reason = sys_errlist[savsyserrno]; } else { (void) sprintf(buf, "unknown error %d -- see intro(2)", savsyserrno); reason - buf; } ewhat = lrqE_EFATAL|lrqE_EINTERNAL; break; } lrqE_error(ewhat, "can't %s %s \"%s\" for %s %s\n\t%s", otext, what, filename, mtext, special, reason); }