Include sys/types.h, sys/stat.h, and errno.h.
(IS_DIRECTORY_SEP): New macro. (convert_time, is_exec, stat): New functions.
This commit is contained in:
parent
6877092ed6
commit
10fea9c4d2
2 changed files with 153 additions and 0 deletions
|
@ -1,3 +1,9 @@
|
|||
2008-05-09 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* ntlib.c: Include sys/types.h, sys/stat.h, and errno.h.
|
||||
(IS_DIRECTORY_SEP): New macro.
|
||||
(convert_time, is_exec, stat): New functions.
|
||||
|
||||
2008-05-08 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* makefile.w32-in (lisp2): Rename epa-file-hook.elc to epa-hook.elc.
|
||||
|
|
147
lib-src/ntlib.c
147
lib-src/ntlib.c
|
@ -27,6 +27,9 @@ Boston, MA 02110-1301, USA.
|
|||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <direct.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "ntlib.h"
|
||||
|
||||
|
@ -210,5 +213,149 @@ sys_chdir (const char * path)
|
|||
return _chdir (path);
|
||||
}
|
||||
|
||||
static FILETIME utc_base_ft;
|
||||
static long double utc_base;
|
||||
static int init = 0;
|
||||
|
||||
static time_t
|
||||
convert_time (FILETIME ft)
|
||||
{
|
||||
long double ret;
|
||||
|
||||
if (CompareFileTime (&ft, &utc_base_ft) < 0)
|
||||
return 0;
|
||||
|
||||
ret = (long double) ft.dwHighDateTime
|
||||
* 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime;
|
||||
ret -= utc_base;
|
||||
return (time_t) (ret * 1e-7L);
|
||||
}
|
||||
|
||||
static int
|
||||
is_exec (const char * name)
|
||||
{
|
||||
char * p = strrchr (name, '.');
|
||||
return
|
||||
(p != NULL
|
||||
&& (stricmp (p, ".exe") == 0 ||
|
||||
stricmp (p, ".com") == 0 ||
|
||||
stricmp (p, ".bat") == 0 ||
|
||||
stricmp (p, ".cmd") == 0));
|
||||
}
|
||||
|
||||
#define IS_DIRECTORY_SEP(x) ((x) == '/' || (x) == '\\')
|
||||
|
||||
/* We need this because nt/inc/sys/stat.h defines struct stat that is
|
||||
incompatible with the MS run-time libraries. */
|
||||
int
|
||||
stat (const char * path, struct stat * buf)
|
||||
{
|
||||
WIN32_FIND_DATA wfd;
|
||||
HANDLE fh;
|
||||
int permission;
|
||||
int len;
|
||||
int rootdir = FALSE;
|
||||
char *name = alloca (FILENAME_MAX);
|
||||
|
||||
if (!init)
|
||||
{
|
||||
/* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */
|
||||
SYSTEMTIME st;
|
||||
|
||||
st.wYear = 1970;
|
||||
st.wMonth = 1;
|
||||
st.wDay = 1;
|
||||
st.wHour = 0;
|
||||
st.wMinute = 0;
|
||||
st.wSecond = 0;
|
||||
st.wMilliseconds = 0;
|
||||
|
||||
SystemTimeToFileTime (&st, &utc_base_ft);
|
||||
utc_base = (long double) utc_base_ft.dwHighDateTime
|
||||
* 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime;
|
||||
init = 1;
|
||||
}
|
||||
|
||||
if (path == NULL || buf == NULL || *path == '\0')
|
||||
{
|
||||
errno = EFAULT;
|
||||
return -1;
|
||||
}
|
||||
if (_mbspbrk (path, "*?|<>\""))
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy (name, path);
|
||||
/* Remove trailing directory separator, unless name is the root
|
||||
directory of a drive in which case ensure there is a trailing
|
||||
separator. */
|
||||
len = strlen (name);
|
||||
rootdir = IS_DIRECTORY_SEP (name[0])
|
||||
|| (len == 3 && name[1] == ':' && IS_DIRECTORY_SEP (name[2]));
|
||||
if (rootdir)
|
||||
{
|
||||
if (GetDriveType (name) < 2)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
memset (&wfd, 0, sizeof (wfd));
|
||||
wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||
wfd.ftCreationTime = utc_base_ft;
|
||||
wfd.ftLastAccessTime = utc_base_ft;
|
||||
wfd.ftLastWriteTime = utc_base_ft;
|
||||
strcpy (wfd.cFileName, name);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IS_DIRECTORY_SEP (name[len-1]))
|
||||
name[len - 1] = 0;
|
||||
|
||||
fh = FindFirstFile (name, &wfd);
|
||||
if (fh == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
FindClose (fh);
|
||||
}
|
||||
buf->st_mode = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ?
|
||||
S_IFDIR : S_IFREG;
|
||||
buf->st_nlink = 1;
|
||||
buf->st_ino = 0;
|
||||
|
||||
if (name[0] && name[1] == ':')
|
||||
buf->st_dev = tolower (name[0]) - 'a' + 1;
|
||||
else
|
||||
buf->st_dev = _getdrive ();
|
||||
buf->st_rdev = buf->st_dev;
|
||||
|
||||
buf->st_size = wfd.nFileSizeLow;
|
||||
|
||||
/* Convert timestamps to Unix format. */
|
||||
buf->st_mtime = convert_time (wfd.ftLastWriteTime);
|
||||
buf->st_atime = convert_time (wfd.ftLastAccessTime);
|
||||
if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
|
||||
buf->st_ctime = convert_time (wfd.ftCreationTime);
|
||||
if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
|
||||
|
||||
/* determine rwx permissions */
|
||||
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
||||
permission = S_IREAD;
|
||||
else
|
||||
permission = S_IREAD | S_IWRITE;
|
||||
|
||||
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
permission |= S_IEXEC;
|
||||
else if (is_exec (name))
|
||||
permission |= S_IEXEC;
|
||||
|
||||
buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* arch-tag: 7b63fb83-70ee-4124-8822-54e53e5d0773
|
||||
(do not change this comment) */
|
||||
|
|
Loading…
Add table
Reference in a new issue