Mail Archives: cygwin-developers/2002/07/22/12:40:46
--Boundary_(ID_anaKV4EUkCCb+eZCqXcLMA)
Content-type: text/plain; charset=us-ascii
Content-transfer-encoding: 7BIT
Content-disposition: inline
I guess that I found the complement of the following:
http://cygwin.com/ml/cygwin-developers/2002-05/msg00008.html
while tracking down some regressions with Cygwin Python CVS. :,)
The attached test program, j7.cc, demonstrates the problem:
$ >file
$ j7 file
dir
The root cause of the problem is that symlink_info::check() ignores the
ERROR_ACCESS_DENIED case in the following:
fileattr = GetFileAttributes (suffix.path);
if (fileattr == INVALID_FILE_ATTRIBUTES)
{
/* The GetFileAttributes call can fail for reasons that don't
matter, so we just return 0. For example, getting the
attributes of \\HOST will typically fail. */
debug_printf ("GetFileAttributes (%s) failed", suffix.path);
error = geterrno_from_win_error (GetLastError (), EACCES);
continue;
}
The above causes path_conv::check() to the lop off the tail component of
the recently deleted file so that path_conv::fileattr incorrectly
indicates a directory instead of a file. This in turn, causes fstat()
to incorrectly indicate that the file descriptor is a directory instead
of a file.
Unfortunately, once again I do not know the best way to fix this
problem. Should fstat() (and cousins) just return EACCES in this case?
BTW, this would fix the Cygwin Python regressions:
static PyFileObject*
dircheck(PyFileObject* f)
{
struct stat buf;
if (f->f_fp == NULL)
return f;
if (fstat(fileno(f->f_fp), &buf) == 0 &&
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
S_ISDIR(buf.st_mode)) {
char *msg = strerror(EISDIR);
PyObject *exc = PyObject_CallFunction(PyExc_IOError, ...
PyErr_SetObject(PyExc_IOError, exc);
return NULL;
}
return f;
}
Thanks,
Jason
--Boundary_(ID_anaKV4EUkCCb+eZCqXcLMA)
Content-type: text/plain; charset=us-ascii; NAME=j7.cc
Content-transfer-encoding: 7BIT
Content-disposition: attachment; filename=j7.cc
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
int
main(int argc, char* argv[])
{
char* file = argv[1];
FILE* fp = fopen(file, "wb+");
if (!fp)
{
printf("fopen(%s) failed with errno = %d\n", file, errno);
return 1;
}
int status = remove(file);
if (status < 0)
{
printf("remove(%s) failed with errno = %d\n", file, errno);
return 2;
}
struct stat buf;
status = fstat(fileno(fp), &buf);
if (status < 0)
printf("fstat() failed with errno = %d\n", errno);
if (S_ISDIR(buf.st_mode))
printf("dir\n");
else
printf("not dir\n");
return 0;
}
--Boundary_(ID_anaKV4EUkCCb+eZCqXcLMA)--
- Raw text -