comparison src/nt.c @ 448:3078fd1074e8 r21-2-39

Import from CVS: tag r21-2-39
author cvs
date Mon, 13 Aug 2007 11:38:25 +0200
parents abe6d1db359e
children c33ae14dd6d0
comparison
equal deleted inserted replaced
447:4fc5f13f3bd3 448:3078fd1074e8
1376 (file-exist "d:\\tmp") =>> t, when d:\tmp exists. Whenever 1376 (file-exist "d:\\tmp") =>> t, when d:\tmp exists. Whenever
1377 we opt to use non-encapsulated stat(), this should serve as 1377 we opt to use non-encapsulated stat(), this should serve as
1378 a compatibility test. --kkm */ 1378 a compatibility test. --kkm */
1379 1379
1380 /* Since stat is encapsulated on Windows NT, we need to encapsulate 1380 /* Since stat is encapsulated on Windows NT, we need to encapsulate
1381 the equally broken fstat as well. */ 1381 the equally broken fstat as well. FSFmacs also provides its own
1382 utime. Is that necessary here too? */
1382 int 1383 int
1383 mswindows_fstat (int handle, struct stat *buffer) 1384 mswindows_fstat (int desc, struct stat * buf)
1384 { 1385 {
1385 int ret; 1386 HANDLE fh = (HANDLE) _get_osfhandle (desc);
1386 BY_HANDLE_FILE_INFORMATION lpFileInfo; 1387 BY_HANDLE_FILE_INFORMATION info;
1387 /* Initialize values */ 1388 DWORD fake_inode;
1388 buffer->st_mode = 0; 1389 int permission;
1389 buffer->st_size = 0; 1390
1390 buffer->st_dev = 0; 1391 switch (GetFileType (fh) & ~FILE_TYPE_REMOTE)
1391 buffer->st_rdev = 0; 1392 {
1392 buffer->st_atime = 0; 1393 case FILE_TYPE_DISK:
1393 buffer->st_ctime = 0; 1394 buf->st_mode = _S_IFREG;
1394 buffer->st_mtime = 0; 1395 if (!GetFileInformationByHandle (fh, &info))
1395 buffer->st_nlink = 0; 1396 {
1396 ret = GetFileInformationByHandle((HANDLE) _get_osfhandle(handle), &lpFileInfo); 1397 errno = EACCES;
1397 if (!ret) 1398 return -1;
1398 { 1399 }
1399 return -1; 1400 break;
1401 case FILE_TYPE_PIPE:
1402 buf->st_mode = _S_IFIFO;
1403 goto non_disk;
1404 case FILE_TYPE_CHAR:
1405 case FILE_TYPE_UNKNOWN:
1406 default:
1407 buf->st_mode = _S_IFCHR;
1408 non_disk:
1409 memset (&info, 0, sizeof (info));
1410 info.dwFileAttributes = 0;
1411 info.ftCreationTime = utc_base_ft;
1412 info.ftLastAccessTime = utc_base_ft;
1413 info.ftLastWriteTime = utc_base_ft;
1414 }
1415
1416 if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1417 {
1418 buf->st_mode = _S_IFDIR;
1419 buf->st_nlink = 2; /* doesn't really matter */
1420 fake_inode = 0; /* this doesn't either I think */
1400 } 1421 }
1401 else 1422 else
1402 { 1423 {
1403 buffer->st_mtime = convert_time (lpFileInfo.ftLastWriteTime); 1424 buf->st_nlink = info.nNumberOfLinks;
1404 buffer->st_atime = convert_time (lpFileInfo.ftLastAccessTime); 1425 /* Might as well use file index to fake inode values, but this
1405 if (buffer->st_atime == 0) buffer->st_atime = buffer->st_mtime; 1426 is not guaranteed to be unique unless we keep a handle open
1406 buffer->st_ctime = convert_time (lpFileInfo.ftCreationTime); 1427 all the time (even then there are situations where it is
1407 if (buffer->st_ctime == 0) buffer->st_ctime = buffer->st_mtime; 1428 not unique). Reputedly, there are at most 48 bits of info
1408 buffer->st_size = lpFileInfo.nFileSizeLow; 1429 (on NTFS, presumably less on FAT). */
1409 buffer->st_nlink = (short) lpFileInfo.nNumberOfLinks; 1430 fake_inode = info.nFileIndexLow ^ info.nFileIndexHigh;
1410 return 0; 1431 }
1411 } 1432
1433 /* MSVC defines _ino_t to be short; other libc's might not. */
1434 if (sizeof (buf->st_ino) == 2)
1435 buf->st_ino = fake_inode ^ (fake_inode >> 16);
1436 else
1437 buf->st_ino = fake_inode;
1438
1439 /* consider files to belong to current user */
1440 buf->st_uid = 0;
1441 buf->st_gid = 0;
1442
1443 buf->st_dev = info.dwVolumeSerialNumber;
1444 buf->st_rdev = info.dwVolumeSerialNumber;
1445
1446 buf->st_size = info.nFileSizeLow;
1447
1448 /* Convert timestamps to Unix format. */
1449 buf->st_mtime = convert_time (info.ftLastWriteTime);
1450 buf->st_atime = convert_time (info.ftLastAccessTime);
1451 if (buf->st_atime == 0) buf->st_atime = buf->st_mtime;
1452 buf->st_ctime = convert_time (info.ftCreationTime);
1453 if (buf->st_ctime == 0) buf->st_ctime = buf->st_mtime;
1454
1455 /* determine rwx permissions */
1456 if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
1457 permission = _S_IREAD;
1458 else
1459 permission = _S_IREAD | _S_IWRITE;
1460
1461 if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
1462 permission |= _S_IEXEC;
1463
1464 buf->st_mode |= permission | (permission >> 3) | (permission >> 6);
1465
1466 return 0;
1412 } 1467 }
1413 1468
1414 /* MSVC stat function can't cope with UNC names and has other bugs, so 1469 /* MSVC stat function can't cope with UNC names and has other bugs, so
1415 replace it with our own. This also allows us to calculate consistent 1470 replace it with our own. This also allows us to calculate consistent
1416 inode values without hacks in the main Emacs code. */ 1471 inode values without hacks in the main Emacs code. */