X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=src%2Fnt.c;h=0824e2a2ecdb8e5c5efee322c98a6d3631877944;hb=c609a628cc0f0096811d90ebc3bb2bbe9e04e8ad;hp=63f682e7f2446dba2aba3393cb1f41fd7e633777;hpb=59eec5f21669e81977b5b1fe9bf717cab49cf7fb;p=chise%2Fxemacs-chise.git diff --git a/src/nt.c b/src/nt.c index 63f682e..0824e2a 100644 --- a/src/nt.c +++ b/src/nt.c @@ -48,7 +48,7 @@ extern Lisp_Object Vwin32_generate_fake_inodes; #endif extern Lisp_Object Vmswindows_get_true_file_attributes; -int nt_fake_unix_uid; +Fixnum nt_fake_unix_uid; static char startup_dir[ MAXPATHLEN ]; @@ -1378,37 +1378,92 @@ generate_inode_val (const char * name) a compatibility test. --kkm */ /* Since stat is encapsulated on Windows NT, we need to encapsulate - the equally broken fstat as well. */ + the equally broken fstat as well. FSFmacs also provides its own + utime. Is that necessary here too? */ int -mswindows_fstat (int handle, struct stat *buffer) +mswindows_fstat (int desc, struct stat * buf) { - int ret; - BY_HANDLE_FILE_INFORMATION lpFileInfo; - /* Initialize values */ - buffer->st_mode = 0; - buffer->st_size = 0; - buffer->st_dev = 0; - buffer->st_rdev = 0; - buffer->st_atime = 0; - buffer->st_ctime = 0; - buffer->st_mtime = 0; - buffer->st_nlink = 0; - ret = GetFileInformationByHandle((HANDLE) _get_osfhandle(handle), &lpFileInfo); - if (!ret) + HANDLE fh = (HANDLE) _get_osfhandle (desc); + BY_HANDLE_FILE_INFORMATION info; + DWORD fake_inode; + int permission; + + switch (GetFileType (fh) & ~FILE_TYPE_REMOTE) { - return -1; + case FILE_TYPE_DISK: + buf->st_mode = _S_IFREG; + if (!GetFileInformationByHandle (fh, &info)) + { + errno = EACCES; + return -1; + } + break; + case FILE_TYPE_PIPE: + buf->st_mode = _S_IFIFO; + goto non_disk; + case FILE_TYPE_CHAR: + case FILE_TYPE_UNKNOWN: + default: + buf->st_mode = _S_IFCHR; + non_disk: + memset (&info, 0, sizeof (info)); + info.dwFileAttributes = 0; + info.ftCreationTime = utc_base_ft; + info.ftLastAccessTime = utc_base_ft; + info.ftLastWriteTime = utc_base_ft; + } + + if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + buf->st_mode = _S_IFDIR; + buf->st_nlink = 2; /* doesn't really matter */ + fake_inode = 0; /* this doesn't either I think */ } else { - buffer->st_mtime = convert_time (lpFileInfo.ftLastWriteTime); - buffer->st_atime = convert_time (lpFileInfo.ftLastAccessTime); - if (buffer->st_atime == 0) buffer->st_atime = buffer->st_mtime; - buffer->st_ctime = convert_time (lpFileInfo.ftCreationTime); - if (buffer->st_ctime == 0) buffer->st_ctime = buffer->st_mtime; - buffer->st_size = lpFileInfo.nFileSizeLow; - buffer->st_nlink = (short) lpFileInfo.nNumberOfLinks; - return 0; + buf->st_nlink = info.nNumberOfLinks; + /* Might as well use file index to fake inode values, but this + is not guaranteed to be unique unless we keep a handle open + all the time (even then there are situations where it is + not unique). Reputedly, there are at most 48 bits of info + (on NTFS, presumably less on FAT). */ + fake_inode = info.nFileIndexLow ^ info.nFileIndexHigh; } + + /* MSVC defines _ino_t to be short; other libc's might not. */ + if (sizeof (buf->st_ino) == 2) + buf->st_ino = fake_inode ^ (fake_inode >> 16); + else + buf->st_ino = fake_inode; + + /* consider files to belong to current user */ + buf->st_uid = 0; + buf->st_gid = 0; + + buf->st_dev = info.dwVolumeSerialNumber; + buf->st_rdev = info.dwVolumeSerialNumber; + + buf->st_size = info.nFileSizeLow; + + /* Convert timestamps to Unix format. */ + buf->st_mtime = convert_time (info.ftLastWriteTime); + buf->st_atime = convert_time (info.ftLastAccessTime); + if (buf->st_atime == 0) buf->st_atime = buf->st_mtime; + buf->st_ctime = convert_time (info.ftCreationTime); + if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime; + + /* determine rwx permissions */ + if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) + permission = _S_IREAD; + else + permission = _S_IREAD | _S_IWRITE; + + if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + permission |= _S_IEXEC; + + buf->st_mode |= permission | (permission >> 3) | (permission >> 6); + + return 0; } /* MSVC stat function can't cope with UNC names and has other bugs, so