| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
| 5 */ | 5 */ |
| 6 | 6 |
| 7 /* | 7 /* |
| 8 * NaCl Service Runtime. I/O Descriptor / Handle abstraction. Memory | 8 * NaCl Service Runtime. I/O Descriptor / Handle abstraction. Memory |
| 9 * mapping using descriptors. | 9 * mapping using descriptors. |
| 10 */ | 10 */ |
| 11 #include "native_client/src/include/portability.h" | 11 #include "native_client/src/include/portability.h" |
| 12 #include "native_client/src/include/portability_io.h" | 12 #include "native_client/src/include/portability_io.h" |
| 13 | 13 |
| 14 #include <windows.h> | 14 #include <windows.h> |
| 15 #include <direct.h> | 15 #include <direct.h> |
| 16 #include <io.h> | 16 #include <io.h> |
| 17 #include <sys/types.h> | 17 #include <sys/types.h> |
| 18 #include <sys/stat.h> | 18 #include <sys/utime.h> |
| 19 #include <share.h> | 19 #include <share.h> |
| 20 #include <accctrl.h> |
| 21 #include <aclapi.h> |
| 20 | 22 |
| 21 #include "native_client/src/include/nacl_macros.h" | 23 #include "native_client/src/include/nacl_macros.h" |
| 22 #include "native_client/src/include/nacl_platform.h" | 24 #include "native_client/src/include/nacl_platform.h" |
| 23 #include "native_client/src/shared/platform/nacl_check.h" | 25 #include "native_client/src/shared/platform/nacl_check.h" |
| 24 #include "native_client/src/shared/platform/nacl_find_addrsp.h" | 26 #include "native_client/src/shared/platform/nacl_find_addrsp.h" |
| 25 #include "native_client/src/shared/platform/nacl_host_desc.h" | 27 #include "native_client/src/shared/platform/nacl_host_desc.h" |
| 26 #include "native_client/src/shared/platform/nacl_log.h" | 28 #include "native_client/src/shared/platform/nacl_log.h" |
| 27 #include "native_client/src/shared/platform/nacl_sync.h" | 29 #include "native_client/src/shared/platform/nacl_sync.h" |
| 28 #include "native_client/src/shared/platform/nacl_sync_checked.h" | 30 #include "native_client/src/shared/platform/nacl_sync_checked.h" |
| 29 #include "native_client/src/shared/platform/win/xlate_system_error.h" | 31 #include "native_client/src/shared/platform/win/xlate_system_error.h" |
| 30 #include "native_client/src/trusted/desc/nacl_desc_effector.h" | 32 #include "native_client/src/trusted/desc/nacl_desc_effector.h" |
| 31 #include "native_client/src/trusted/desc/nacl_desc_effector_trusted_mem.h" | 33 #include "native_client/src/trusted/desc/nacl_desc_effector_trusted_mem.h" |
| 32 | 34 |
| 33 #include "native_client/src/trusted/service_runtime/nacl_config.h" | 35 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
| 34 #include "native_client/src/trusted/service_runtime/internal_errno.h" | 36 #include "native_client/src/trusted/service_runtime/internal_errno.h" |
| 35 #include "native_client/src/trusted/service_runtime/sel_util-inl.h" | 37 #include "native_client/src/trusted/service_runtime/sel_util-inl.h" |
| 36 | 38 |
| 37 #include "native_client/src/trusted/service_runtime/include/bits/mman.h" | 39 #include "native_client/src/trusted/service_runtime/include/bits/mman.h" |
| 40 #include "native_client/src/trusted/service_runtime/include/bits/stat.h" |
| 38 #include "native_client/src/trusted/service_runtime/include/sys/errno.h" | 41 #include "native_client/src/trusted/service_runtime/include/sys/errno.h" |
| 39 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" | 42 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h" |
| 40 #include "native_client/src/trusted/service_runtime/include/sys/stat.h" | |
| 41 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h" | 43 #include "native_client/src/trusted/service_runtime/include/sys/unistd.h" |
| 42 | 44 |
| 43 #define OFFSET_FOR_FILEPOS_LOCK (GG_LONGLONG(0x7000000000000000)) | 45 #define OFFSET_FOR_FILEPOS_LOCK (GG_LONGLONG(0x7000000000000000)) |
| 44 | 46 |
| 45 /* | 47 /* |
| 46 * By convention, we use locking the byte at OFFSET_FOR_FILEPOS_LOCK | 48 * By convention, we use locking the byte at OFFSET_FOR_FILEPOS_LOCK |
| 47 * as locking for the implicit file position associated with a file | 49 * as locking for the implicit file position associated with a file |
| 48 * handle. According to MSDN, LockFileEx of a byte range that does | 50 * handle. According to MSDN, LockFileEx of a byte range that does |
| 49 * not (yet) exist in a file is not an error, which makes sense in | 51 * not (yet) exist in a file is not an error, which makes sense in |
| 50 * that one might want to have exclusive access to a file region that | 52 * that one might want to have exclusive access to a file region that |
| (...skipping 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1438 NaClLog(3, "NaClHostDescUnlink: _chmod failed: %d\n", errno); | 1440 NaClLog(3, "NaClHostDescUnlink: _chmod failed: %d\n", errno); |
| 1439 } | 1441 } |
| 1440 } | 1442 } |
| 1441 | 1443 |
| 1442 if (_unlink(path) != 0) | 1444 if (_unlink(path) != 0) |
| 1443 return -NaClXlateErrno(errno); | 1445 return -NaClXlateErrno(errno); |
| 1444 | 1446 |
| 1445 return 0; | 1447 return 0; |
| 1446 } | 1448 } |
| 1447 | 1449 |
| 1448 int NaClHostDescTruncate(char const *path, nacl_abi_off_t length) { | 1450 int DoTruncate(HANDLE hfile, nacl_abi_off_t length) { |
| 1449 LARGE_INTEGER win_length; | 1451 LARGE_INTEGER win_length; |
| 1450 DWORD err; | 1452 DWORD err; |
| 1451 | 1453 |
| 1452 HANDLE hfile = CreateFileA(path, | |
| 1453 GENERIC_READ | GENERIC_WRITE, | |
| 1454 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, | |
| 1455 NULL, | |
| 1456 OPEN_EXISTING, | |
| 1457 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_POSIX_SEMANTICS, | |
| 1458 NULL); | |
| 1459 | |
| 1460 if (INVALID_HANDLE_VALUE == hfile) { | |
| 1461 err = GetLastError(); | |
| 1462 NaClLog(3, "NaClHostDescTruncate: CreateFile failed %d\n", err); | |
| 1463 return -NaClXlateSystemError(err); | |
| 1464 } | |
| 1465 | |
| 1466 win_length.QuadPart = length; | 1454 win_length.QuadPart = length; |
| 1467 if (!SetFilePointerEx(hfile, win_length, NULL, FILE_BEGIN)) { | 1455 if (!SetFilePointerEx(hfile, win_length, NULL, FILE_BEGIN)) { |
| 1468 err = GetLastError(); | 1456 err = GetLastError(); |
| 1469 NaClLog(LOG_ERROR, | 1457 NaClLog(LOG_ERROR, |
| 1470 "NaClHostDescTruncate: SetFilePointerEx failed:" | 1458 "NaClHostDescTruncate: SetFilePointerEx failed:" |
| 1471 " last error %d.\n", err); | 1459 " last error %d.\n", err); |
| 1472 return -NaClXlateSystemError(err); | 1460 return -NaClXlateSystemError(err); |
| 1473 } | 1461 } |
| 1474 | 1462 |
| 1475 if (!SetEndOfFile(hfile)) { | 1463 if (!SetEndOfFile(hfile)) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1506 | 1494 |
| 1507 int NaClHostDescRename(const char *oldpath, const char *newpath) { | 1495 int NaClHostDescRename(const char *oldpath, const char *newpath) { |
| 1508 if (rename(oldpath, newpath) != 0) | 1496 if (rename(oldpath, newpath) != 0) |
| 1509 return -NaClXlateErrno(errno); | 1497 return -NaClXlateErrno(errno); |
| 1510 return 0; | 1498 return 0; |
| 1511 } | 1499 } |
| 1512 | 1500 |
| 1513 int NaClHostDescSymlink(const char *oldpath, const char *newpath) { | 1501 int NaClHostDescSymlink(const char *oldpath, const char *newpath) { |
| 1514 /* | 1502 /* |
| 1515 * Symlinks are not supported on win32. | 1503 * Symlinks are not supported on win32. |
| 1504 * TODO(smklein): symlink |
| 1516 */ | 1505 */ |
| 1517 NaClLog(1, "NaClHostDescSymlink: symbolic links not supported on windows.\n"); | 1506 NaClLog(1, "NaClHostDescSymlink: symbolic links not supported on windows.\n"); |
| 1518 return -NACL_ABI_ENOSYS; | 1507 return -NACL_ABI_ENOSYS; |
| 1519 } | 1508 } |
| 1520 | 1509 |
| 1521 int NaClHostDescChmod(const char *path, nacl_abi_mode_t mode) { | 1510 int NaClHostDescChmod(const char *path, nacl_abi_mode_t mode) { |
| 1522 if (_chmod(path, NaClMapMode(mode)) != 0) | 1511 if (_chmod(path, NaClMapMode(mode)) != 0) |
| 1523 return -NaClXlateErrno(errno); | 1512 return -NaClXlateErrno(errno); |
| 1524 return 0; | 1513 return 0; |
| 1525 } | 1514 } |
| 1526 | 1515 |
| 1527 int NaClHostDescAccess(const char *path, int amode) { | 1516 int NaClHostDescAccess(const char *path, int amode) { |
| 1528 if (_access(path, NaClMapAccessMode(amode)) != 0) | 1517 if (_access_s(path, NaClMapAccessMode(amode)) != 0) |
| 1529 return -NaClXlateErrno(errno); | 1518 return -NaClXlateErrno(errno); |
| 1530 return 0; | 1519 return 0; |
| 1531 } | 1520 } |
| 1532 | 1521 |
| 1533 int NaClHostDescReadlink(const char *path, char *buf, size_t bufsize) { | 1522 int NaClHostDescReadlink(const char *path, char *buf, size_t bufsize) { |
| 1534 /* | 1523 /* |
| 1535 * readlink(2) sets errno to EINVAL when the file in question is | 1524 * readlink(2) sets errno to EINVAL when the file in question is |
| 1536 * not a symlink. Since win32 does not support symlinks we simply | 1525 * not a symlink. Since win32 does not support symlinks we simply |
| 1537 * return EINVAL in all cases here. | 1526 * return EINVAL in all cases here. |
| 1527 * |
| 1528 * Partial implementation exists here: |
| 1529 * https://chromiumcodereview.appspot.com/24889002/ |
| 1530 * TODO(phosek/smklein): Finish implementing |
| 1538 */ | 1531 */ |
| 1539 NaClLog(1, | 1532 NaClLog(1, |
| 1540 "NaClHostDescReadlink: symbolic links not supported on Windows.\n"); | 1533 "NaClHostDescReadlink: symbolic links are not supported on Windows\n")
; |
| 1541 return -NACL_ABI_EINVAL; | 1534 return -NACL_ABI_EINVAL; |
| 1542 } | 1535 } |
| 1536 |
| 1537 int NaClHostDescUtimes(const char *filename, |
| 1538 const struct nacl_abi_timeval *times) { |
| 1539 struct _utimbuf host_time; |
| 1540 if (times != NULL) { |
| 1541 host_time.actime = times[0].nacl_abi_tv_sec; |
| 1542 host_time.modtime = times[1].nacl_abi_tv_sec; |
| 1543 } |
| 1544 NaClLog(1, "UTIMES BEING CALLED\n"); |
| 1545 if (_utime(filename, (times != NULL ? &host_time : NULL)) == -1) { |
| 1546 return -NaClXlateErrno(errno); |
| 1547 } |
| 1548 return 0; |
| 1549 } |
| 1550 |
| 1551 int NaClHostDescFcntl(struct NaClHostDesc *d, int cmd, long arg) { |
| 1552 NaClHostDescCheckValidity("NaClHostDescFcntl", d); |
| 1553 /* |
| 1554 * TODO(phosek/smklein): Implement this function. |
| 1555 */ |
| 1556 NaClLog(1, |
| 1557 "NaClHostDescFcntl: Fcntl not yet supported on Windows.\n"); |
| 1558 return -NACL_ABI_EINVAL; |
| 1559 } |
| 1560 |
| 1561 int NaClHostDescFchmod(struct NaClHostDesc *d, nacl_abi_mode_t mode) { |
| 1562 NaClHostDescCheckValidity("NaClHostDescFchmod", d); |
| 1563 /* |
| 1564 * TODO(smklein): Use the following |
| 1565 * https://msdn.microsoft.com/en-us/library/ks2530z6.aspx |
| 1566 * and |
| 1567 * https://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx |
| 1568 * to get the path. Then, call chmod |
| 1569 */ |
| 1570 NaClLog(1, |
| 1571 "NaClHostDescFchmod: Fchmod not yet supported on Windows.\n"); |
| 1572 return -NACL_ABI_EINVAL; |
| 1573 } |
| 1574 |
| 1575 int NaClHostDescFsync(struct NaClHostDesc *d) { |
| 1576 HANDLE hFile; |
| 1577 DWORD err; |
| 1578 |
| 1579 NaClHostDescCheckValidity("NaClHostDescFsync", d); |
| 1580 |
| 1581 hFile = (HANDLE) _get_osfhandle(d->d); |
| 1582 CHECK(INVALID_HANDLE_VALUE != hFile); |
| 1583 |
| 1584 if (!FlushFileBuffers(hFile)) { |
| 1585 err = GetLastError(); |
| 1586 return -NaClXlateSystemError(err); |
| 1587 } |
| 1588 |
| 1589 return 0; |
| 1590 } |
| 1591 |
| 1592 int NaClHostDescFdatasync(struct NaClHostDesc *d) { |
| 1593 HANDLE hFile; |
| 1594 DWORD err; |
| 1595 |
| 1596 NaClHostDescCheckValidity("NaClHostDescFdatasync", d); |
| 1597 |
| 1598 hFile = (HANDLE) _get_osfhandle(d->d); |
| 1599 CHECK(INVALID_HANDLE_VALUE != hFile); |
| 1600 |
| 1601 if (!FlushFileBuffers(hFile)) { |
| 1602 err = GetLastError(); |
| 1603 return -NaClXlateSystemError(err); |
| 1604 } |
| 1605 |
| 1606 return 0; |
| 1607 } |
| 1608 |
| 1609 int NaClHostDescFtruncate(struct NaClHostDesc *d, nacl_off64_t length) { |
| 1610 NaClHostDescCheckValidity("NaClHostDescFtruncate", d); |
| 1611 |
| 1612 return DoTruncate((HANDLE) _get_osfhandle(d->d), length); |
| 1613 } |
| 1614 |
| 1615 int NaClHostDescTruncate(char const *path, nacl_abi_off_t length) { |
| 1616 int retval; |
| 1617 |
| 1618 HANDLE hfile = CreateFileA(path, |
| 1619 GENERIC_READ | GENERIC_WRITE, |
| 1620 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, |
| 1621 NULL, |
| 1622 OPEN_EXISTING, |
| 1623 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_POSIX_SEMANTICS, |
| 1624 NULL); |
| 1625 |
| 1626 if (INVALID_HANDLE_VALUE == hfile) { |
| 1627 DWORD err = GetLastError(); |
| 1628 NaClLog(3, "NaClHostDescTruncate: CreateFileA failed %d\n", err); |
| 1629 return -NaClXlateSystemError(err); |
| 1630 } |
| 1631 |
| 1632 retval = DoTruncate(hfile, length); |
| 1633 |
| 1634 if (!CloseHandle(hfile)) { |
| 1635 DWORD err = GetLastError(); |
| 1636 NaClLog(3, "NaClHostDescTruncate: CloseHandle failed %d\n", err); |
| 1637 if (retval == 0) |
| 1638 retval = -NaClXlateSystemError(err); |
| 1639 } |
| 1640 |
| 1641 return retval; |
| 1642 } |
| OLD | NEW |