"Juan Lang" juan_lang@yahoo.com wrote:
- buf->st_mode = S_IFREG;
- if (!(hfi.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)))
- {
- buf->st_mode |= S_IREAD;
- if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
buf->st_mode |= S_IWRITE;
- }
Why do you take into account (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) at all? They have nothing to do with an ability to read/write files. What you probably need to consider is a type of a file passed in.
--- Dmitry Timoshkov dmitry@baikal.ru wrote:
Why do you take into account (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM) at all? They have nothing to do with an ability to read/write files.
You're right. I didn't do any tests, it was just my poor memory.
What you probably need to consider is a type of a file passed in.
Hm? Not sure what you mean here. --Juan
__________________________________ Do you Yahoo!? Yahoo! Mail - You care about security. So do we. http://promotions.yahoo.com/new_mail
"Juan Lang" juan_lang@yahoo.com wrote:
What you probably need to consider is a type of a file passed in.
Hm? Not sure what you mean here.
Apparently a returned info should be based on whether a file handle resembles an ordinary disk based file, or pipe, or device, or something else. But that's a target for a separate patch.
--- Dmitry Timoshkov dmitry@baikal.ru wrote:
Apparently a returned info should be based on whether a file handle resembles an ordinary disk based file, or pipe, or device, or something else. But that's a target for a separate patch.
Got it. How's this? --Juan
__________________________________ Do you Yahoo!? Meet the all-new My Yahoo! - Try it today! http://my.yahoo.com
"Juan Lang" juan_lang@yahoo.com wrote:
Got it. How's this?
- dw = GetFileType(hand);
- buf->st_mode = S_IREAD;
- if (!(hfi.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
- buf->st_mode |= S_IWRITE;
- if (hfi.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- buf->st_mode |= S_IFDIR;
- else if (dw == FILE_TYPE_CHAR)
- buf->st_mode |= S_IFCHR;
- else
- buf->st_mode |= S_IFREG;
- TRACE(":dwFileAttributes = 0x%lx, mode set to 0x%x\n",hfi.dwFileAttributes,
- buf->st_mode);
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. And FILE_TYPE_PIPE perhaps should have _S_IFIFO set. Not sure if it's worth to write a test case for it.
--- Dmitry Timoshkov dmitry@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
#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(); }