msvcrt: set mode bits in _fstati64
Juan Lang
juan_lang at yahoo.com
Sun Dec 5 11:29:42 CST 2004
--- Dmitry Timoshkov <dmitry at baikal.ru> wrote:
> Looks better, except that according to MSDN "_S_IFREG bit is set if path
> specifies
> an ordinary file or a device", so you need to add a check for
> FILE_TYPE_DISK.
Interestingly, you can't _open the root directory of a drive in Windows;
it fails with ENOENT. You also can't _open a directory; it fails with
ENOACCES. The _S_IFDIR flag never appears to be set, even if you get a
handle to a directory.
The attached test program shows the following output under WinXP:
file c: flags: couldn't open, errno is 14
file c:\ flags: couldn't open, errno is 2
file c:\boot.ini flags: _S_IFREG
file c:\windows flags: couldn't open, errno is 13
directory c: flags: _S_IFREG
directory c:\ flags: _S_IFREG
directory c:\windows flags: _S_IFREG
read pipe flags: _S_IFIFO
write pipe flags: _S_IFIFO
I wasn't really interested in getting this 100% correct; the st_mode set
before was always 0, so it can't be that critical. Mostly I was tired of
fixme's when running MinGW's gcc.exe under wine. So, I'll resubmit a
modified patch that isn't entirely correct but is a little closer, anyway
:)
--Juan
__________________________________
Do you Yahoo!?
Take Yahoo! Mail with you! Get it on your mobile phone.
http://mobile.yahoo.com/maildemo
-------------- next part --------------
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
#include <windows.h>
static int firstFlag = 1;
static printFlag(const char *flag)
{
if (!firstFlag)
printf("| ");
printf(flag);
firstFlag = 0;
}
static void getFDMode(int fd)
{
struct _stat st;
firstFlag = 1;
if (_fstat(fd, &st) == 0)
{
if (st.st_mode & _S_IFCHR)
printFlag("_S_IFCHR");
if (st.st_mode & _S_IFREG)
printFlag("_S_IFREG");
if (st.st_mode & _S_IFDIR)
printFlag("_S_IFDIR");
if (st.st_mode & _S_IFIFO)
printFlag("_S_IFIFO");
}
putchar('\n');
}
static void getFileMode(const char *file)
{
int fd = _open(file, _O_RDWR, _S_IREAD | _S_IWRITE);
printf("file %s flags: ", file);
if (fd == -1)
fd = _open(file, _O_RDONLY, _S_IREAD);
if (fd != -1)
{
getFDMode(fd);
_close(fd);
}
else
printf("couldn't open, errno is %d\n", errno);
}
static void getPipeMode(void)
{
int fds[2];
if (_pipe(fds, 256, O_BINARY) == 0)
{
printf("read pipe flags: ");
getFDMode(fds[0]);
printf("write pipe flags: ");
getFDMode(fds[1]);
_close(fds[0]);
_close(fds[1]);
}
}
static void getDirectoryMode(const char *directory)
{
HANDLE h = CreateFileA(directory, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
printf("directory %s flags: ", directory);
if (h != INVALID_HANDLE_VALUE)
{
int fd = _open_osfhandle((intptr_t)h, _O_RDONLY);
if (fd != -1)
{
getFDMode(fd);
_close(fd);
}
CloseHandle(h);
}
else
printf("failed with GetLastError() = %ld\n", GetLastError());
}
int main(void)
{
/* expect errno is 13 (EACCES), can't open a device */
getFileMode("c:");
/* expect errno is 2 (ENOENT), can't open a drive */
getFileMode("c:\\");
getFileMode("c:\\boot.ini");
/* expect errno is 13 (EACCES), can't open a directory */
getFileMode("c:\\windows");
getDirectoryMode("c:");
getDirectoryMode("c:\\");
getDirectoryMode("c:\\windows");
getPipeMode();
}
More information about the wine-devel
mailing list