diff options
| author | Eli Zaretskii | 2008-05-09 20:37:32 +0000 |
|---|---|---|
| committer | Eli Zaretskii | 2008-05-09 20:37:32 +0000 |
| commit | 10fea9c4d210182a5bb60f0a537e7c8d5fcb9a9a (patch) | |
| tree | 138a0b0b693b8d725e64e5b9f34cb26fa1e13265 | |
| parent | 6877092ed693b50f487b4b6f4f14e631f4f7045c (diff) | |
| download | emacs-10fea9c4d210182a5bb60f0a537e7c8d5fcb9a9a.tar.gz emacs-10fea9c4d210182a5bb60f0a537e7c8d5fcb9a9a.zip | |
Include sys/types.h, sys/stat.h, and errno.h.
(IS_DIRECTORY_SEP): New macro.
(convert_time, is_exec, stat): New functions.
| -rw-r--r-- | lib-src/ChangeLog | 6 | ||||
| -rw-r--r-- | lib-src/ntlib.c | 147 |
2 files changed, 153 insertions, 0 deletions
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog index 1b64f54cbdd..d0441496474 100644 --- a/lib-src/ChangeLog +++ b/lib-src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2008-05-09 Eli Zaretskii <eliz@gnu.org> | ||
| 2 | |||
| 3 | * ntlib.c: Include sys/types.h, sys/stat.h, and errno.h. | ||
| 4 | (IS_DIRECTORY_SEP): New macro. | ||
| 5 | (convert_time, is_exec, stat): New functions. | ||
| 6 | |||
| 1 | 2008-05-08 Eli Zaretskii <eliz@gnu.org> | 7 | 2008-05-08 Eli Zaretskii <eliz@gnu.org> |
| 2 | 8 | ||
| 3 | * makefile.w32-in (lisp2): Rename epa-file-hook.elc to epa-hook.elc. | 9 | * makefile.w32-in (lisp2): Rename epa-file-hook.elc to epa-hook.elc. |
diff --git a/lib-src/ntlib.c b/lib-src/ntlib.c index 67533894ace..4cfb7ad0625 100644 --- a/lib-src/ntlib.c +++ b/lib-src/ntlib.c | |||
| @@ -27,6 +27,9 @@ Boston, MA 02110-1301, USA. | |||
| 27 | #include <stdio.h> | 27 | #include <stdio.h> |
| 28 | #include <time.h> | 28 | #include <time.h> |
| 29 | #include <direct.h> | 29 | #include <direct.h> |
| 30 | #include <sys/types.h> | ||
| 31 | #include <sys/stat.h> | ||
| 32 | #include <errno.h> | ||
| 30 | 33 | ||
| 31 | #include "ntlib.h" | 34 | #include "ntlib.h" |
| 32 | 35 | ||
| @@ -210,5 +213,149 @@ sys_chdir (const char * path) | |||
| 210 | return _chdir (path); | 213 | return _chdir (path); |
| 211 | } | 214 | } |
| 212 | 215 | ||
| 216 | static FILETIME utc_base_ft; | ||
| 217 | static long double utc_base; | ||
| 218 | static int init = 0; | ||
| 219 | |||
| 220 | static time_t | ||
| 221 | convert_time (FILETIME ft) | ||
| 222 | { | ||
| 223 | long double ret; | ||
| 224 | |||
| 225 | if (CompareFileTime (&ft, &utc_base_ft) < 0) | ||
| 226 | return 0; | ||
| 227 | |||
| 228 | ret = (long double) ft.dwHighDateTime | ||
| 229 | * 4096.0L * 1024.0L * 1024.0L + ft.dwLowDateTime; | ||
| 230 | ret -= utc_base; | ||
| 231 | return (time_t) (ret * 1e-7L); | ||
| 232 | } | ||
| 233 | |||
| 234 | static int | ||
| 235 | is_exec (const char * name) | ||
| 236 | { | ||
| 237 | char * p = strrchr (name, '.'); | ||
| 238 | return | ||
| 239 | (p != NULL | ||
| 240 | && (stricmp (p, ".exe") == 0 || | ||
| 241 | stricmp (p, ".com") == 0 || | ||
| 242 | stricmp (p, ".bat") == 0 || | ||
| 243 | stricmp (p, ".cmd") == 0)); | ||
| 244 | } | ||
| 245 | |||
| 246 | #define IS_DIRECTORY_SEP(x) ((x) == '/' || (x) == '\\') | ||
| 247 | |||
| 248 | /* We need this because nt/inc/sys/stat.h defines struct stat that is | ||
| 249 | incompatible with the MS run-time libraries. */ | ||
| 250 | int | ||
| 251 | stat (const char * path, struct stat * buf) | ||
| 252 | { | ||
| 253 | WIN32_FIND_DATA wfd; | ||
| 254 | HANDLE fh; | ||
| 255 | int permission; | ||
| 256 | int len; | ||
| 257 | int rootdir = FALSE; | ||
| 258 | char *name = alloca (FILENAME_MAX); | ||
| 259 | |||
| 260 | if (!init) | ||
| 261 | { | ||
| 262 | /* Determine the delta between 1-Jan-1601 and 1-Jan-1970. */ | ||
| 263 | SYSTEMTIME st; | ||
| 264 | |||
| 265 | st.wYear = 1970; | ||
| 266 | st.wMonth = 1; | ||
| 267 | st.wDay = 1; | ||
| 268 | st.wHour = 0; | ||
| 269 | st.wMinute = 0; | ||
| 270 | st.wSecond = 0; | ||
| 271 | st.wMilliseconds = 0; | ||
| 272 | |||
| 273 | SystemTimeToFileTime (&st, &utc_base_ft); | ||
| 274 | utc_base = (long double) utc_base_ft.dwHighDateTime | ||
| 275 | * 4096.0L * 1024.0L * 1024.0L + utc_base_ft.dwLowDateTime; | ||
| 276 | init = 1; | ||
| 277 | } | ||
| 278 | |||
| 279 | if (path == NULL || buf == NULL || *path == '\0') | ||
| 280 | { | ||
| 281 | errno = EFAULT; | ||
| 282 | return -1; | ||
| 283 | } | ||
| 284 | if (_mbspbrk (path, "*?|<>\"")) | ||
| 285 | { | ||
| 286 | errno = ENOENT; | ||
| 287 | return -1; | ||
| 288 | } | ||
| 289 | |||
| 290 | strcpy (name, path); | ||
| 291 | /* Remove trailing directory separator, unless name is the root | ||
| 292 | directory of a drive in which case ensure there is a trailing | ||
| 293 | separator. */ | ||
| 294 | len = strlen (name); | ||
| 295 | rootdir = IS_DIRECTORY_SEP (name[0]) | ||
| 296 | || (len == 3 && name[1] == ':' && IS_DIRECTORY_SEP (name[2])); | ||
| 297 | if (rootdir) | ||
| 298 | { | ||
| 299 | if (GetDriveType (name) < 2) | ||
| 300 | { | ||
| 301 | errno = ENOENT; | ||
| 302 | return -1; | ||
| 303 | } | ||
| 304 | memset (&wfd, 0, sizeof (wfd)); | ||
| 305 | wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; | ||
| 306 | wfd.ftCreationTime = utc_base_ft; | ||
| 307 | wfd.ftLastAccessTime = utc_base_ft; | ||
| 308 | wfd.ftLastWriteTime = utc_base_ft; | ||
| 309 | strcpy (wfd.cFileName, name); | ||
| 310 | } | ||
| 311 | else | ||
| 312 | { | ||
| 313 | if (IS_DIRECTORY_SEP (name[len-1])) | ||
| 314 | name[len - 1] = 0; | ||
| 315 | |||
| 316 | fh = FindFirstFile (name, &wfd); | ||
| 317 | if (fh == INVALID_HANDLE_VALUE) | ||
| 318 | { | ||
| 319 | errno = ENOENT; | ||
| 320 | return -1; | ||
| 321 | } | ||
| 322 | FindClose (fh); | ||
| 323 | } | ||
| 324 | buf->st_mode = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? | ||
| 325 | S_IFDIR : S_IFREG; | ||
| 326 | buf->st_nlink = 1; | ||
| 327 | buf->st_ino = 0; | ||
| 328 | |||
| 329 | if (name[0] && name[1] == ':') | ||
| 330 | buf->st_dev = tolower (name[0]) - 'a' + 1; | ||
| 331 | else | ||
| 332 | buf->st_dev = _getdrive (); | ||
| 333 | buf->st_rdev = buf->st_dev; | ||
| 334 | |||
| 335 | buf->st_size = wfd.nFileSizeLow; | ||
| 336 | |||
| 337 | /* Convert timestamps to Unix format. */ | ||
| 338 | buf->st_mtime = convert_time (wfd.ftLastWriteTime); | ||
| 339 | buf->st_atime = convert_time (wfd.ftLastAccessTime); | ||
| 340 | if (buf->st_atime == 0) buf->st_atime = buf->st_mtime; | ||
| 341 | buf->st_ctime = convert_time (wfd.ftCreationTime); | ||
| 342 | if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime; | ||
| 343 | |||
| 344 | /* determine rwx permissions */ | ||
| 345 | if (wfd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) | ||
| 346 | permission = S_IREAD; | ||
| 347 | else | ||
| 348 | permission = S_IREAD | S_IWRITE; | ||
| 349 | |||
| 350 | if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) | ||
| 351 | permission |= S_IEXEC; | ||
| 352 | else if (is_exec (name)) | ||
| 353 | permission |= S_IEXEC; | ||
| 354 | |||
| 355 | buf->st_mode |= permission | (permission >> 3) | (permission >> 6); | ||
| 356 | |||
| 357 | return 0; | ||
| 358 | } | ||
| 359 | |||
| 213 | /* arch-tag: 7b63fb83-70ee-4124-8822-54e53e5d0773 | 360 | /* arch-tag: 7b63fb83-70ee-4124-8822-54e53e5d0773 |
| 214 | (do not change this comment) */ | 361 | (do not change this comment) */ |