KrisWebDev KrisWebDev - 5 months ago 18
Python Question

How to properly handle file read/write errors in C?

I want to rewrite yEnc code to make it compilable on Win32 with Visual Studio 2008.

The issue is that yEnc uses unistd.h (UNIX) functions fcntl to check if a file is readable or writable. It is of course not compatible with MS Visual Studio.

Here's what I want to be remove:

static Bool writable(FILE *file)
{
int mode = fcntl(fileno(file),F_GETFL) & O_ACCMODE;
return (mode == O_WRONLY) || (mode == O_RDWR);
}

static Bool readable(FILE *file)
{
int mode = fcntl(fileno(file),F_GETFL) & O_ACCMODE;
return (mode == O_RDONLY) || (mode == O_RDWR);
}


And here is how it is called:

FILE* infile = PyFile_AsFile(Py_infile);
FILE* outfile = PyFile_AsFile(Py_outfile);

if(!readable(infile) || !writable(outfile) ) {
return PyErr_Format(PyExc_ValueError, "file objects not writeable/readable");
}

/* File stuff including */
fread(&read_buffer, 1, in_ind, infile);
if(ferror(infile) || ferror(outfile)) {
return PyErr_Format(PyExc_IOError, "I/O Error while encoding");
}
fputc(CR, outfile);
fputc(LF, outfile);
fflush(outfile);
/* End of file stuff */


Can someone help me converting this readable/writable check (with equivalent of try {} catch {} instead) ?

I believe it is easier to handle errors on file read/write than trying to know if a Windows file is readable/writable, because there doesn't seem to be simple Windows equivalents to fcntl/F_GETFL.

The solution doesn't seem complicated but as I'm new to C and Python, I don't want to take the risk of making a buggy exception handler.

Thanks for your help.

Answer

Finally, I think the following checks will be sufficient:

infile == NULL
outfile == NULL 
fread != read_count
fwrite != write_count
ferror

This should be sufficient. Moreover, the file have been opened in Python first and I presume this file open has been tested for exceptions.