| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 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 tests for simple syscalls | 8 * NaCl tests for simple syscalls |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <dirent.h> | 11 #include <dirent.h> |
| 12 #include <errno.h> | 12 #include <errno.h> |
| 13 #include <fcntl.h> | 13 #include <fcntl.h> |
| 14 #include <limits.h> | 14 #include <limits.h> |
| 15 #include <sched.h> | 15 #include <sched.h> |
| 16 #include <stdlib.h> | 16 #include <stdlib.h> |
| 17 #include <stdio.h> | 17 #include <stdio.h> |
| 18 #include <string.h> | 18 #include <string.h> |
| 19 #include <sys/stat.h> | 19 #include <sys/stat.h> |
| 20 #include <unistd.h> | 20 #include <unistd.h> |
| 21 #include <utime.h> | |
| 22 | 21 |
| 22 #include "native_client/src/include/build_config.h" |
| 23 #include "native_client/src/include/nacl_assert.h" | 23 #include "native_client/src/include/nacl_assert.h" |
| 24 #include "native_client/src/trusted/service_runtime/nacl_config.h" | 24 #include "native_client/src/trusted/service_runtime/nacl_config.h" |
| 25 #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h" |
| 25 | 26 |
| 26 #define PRINT_HEADER 0 | 27 #define PRINT_HEADER 0 |
| 27 #define TEXT_LINE_SIZE 1024 | 28 #define TEXT_LINE_SIZE 1024 |
| 28 | 29 |
| 30 bool windows = false; |
| 31 |
| 29 /* | 32 /* |
| 30 * TODO(sbc): remove this test once these declarations get added to the | 33 * TODO(sbc): remove this test once these declarations get added to the |
| 31 * newlib toolchain | 34 * newlib toolchain |
| 32 */ | 35 */ |
| 33 #ifndef __GLIBC__ | 36 #ifndef __GLIBC__ |
| 34 extern "C" { | 37 extern "C" { |
| 35 int gethostname(char *name, size_t len); | 38 int gethostname(char *name, size_t len); |
| 36 int utimes(const char *filename, const struct timeval times[2]); | |
| 37 int utime(const char *filename, const struct utimbuf *times); | |
| 38 int eaccess(const char *pathname, int mode); | 39 int eaccess(const char *pathname, int mode); |
| 39 } | 40 } |
| 40 #endif | 41 #endif |
| 41 | 42 |
| 42 /* | 43 /* |
| 43 * function failed(testname, msg) | 44 * function failed(testname, msg) |
| 44 * print failure message and exit with a return code of -1 | 45 * print failure message and exit with a return code of -1 |
| 45 */ | 46 */ |
| 46 bool failed(const char *testname, const char *msg) { | 47 bool failed(const char *testname, const char *msg) { |
| 47 printf("TEST FAILED: %s: %s\n", testname, msg); | 48 printf("TEST FAILED: %s: %s\n", testname, msg); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 | 131 |
| 131 // Simple test that chdir returns zero for '.'. chdir gets more | 132 // Simple test that chdir returns zero for '.'. chdir gets more |
| 132 // significant testing as part of the getcwd test. | 133 // significant testing as part of the getcwd test. |
| 133 bool test_chdir() { | 134 bool test_chdir() { |
| 134 int rtn = chdir("."); | 135 int rtn = chdir("."); |
| 135 ASSERT_EQ_MSG(rtn, 0, "chdir() failed"); | 136 ASSERT_EQ_MSG(rtn, 0, "chdir() failed"); |
| 136 | 137 |
| 137 return passed("test_chdir", "all"); | 138 return passed("test_chdir", "all"); |
| 138 } | 139 } |
| 139 | 140 |
| 141 bool test_fchdir() { |
| 142 char dirname[PATH_MAX] = { '\0' }; |
| 143 char newdir[PATH_MAX] = { '\0' }; |
| 144 char parent[PATH_MAX] = { '\0' }; |
| 145 int retcode; |
| 146 int fd; |
| 147 char *rtn = getcwd(dirname, PATH_MAX); |
| 148 ASSERT_EQ_MSG(rtn, dirname, "getcwd() failed"); |
| 149 |
| 150 // Calculate parent folder. |
| 151 strncpy(parent, dirname, PATH_MAX); |
| 152 char *basename_start; |
| 153 if (windows) { |
| 154 basename_start = strrchr(parent, '\\'); |
| 155 } else { |
| 156 basename_start = strrchr(parent, '/'); |
| 157 } |
| 158 |
| 159 if (basename_start == NULL) { |
| 160 basename_start = strrchr(parent, '\\'); |
| 161 ASSERT_NE_MSG(basename_start, NULL, "test_file contains no dir seperator"); |
| 162 } |
| 163 basename_start[0] = '\0'; |
| 164 |
| 165 // Open parent folder |
| 166 fd = open(parent, O_RDONLY | O_DIRECTORY); |
| 167 ASSERT_NE_MSG(fd, -1, "open() failed to open parent directory"); |
| 168 |
| 169 retcode = NACL_SYSCALL(fchdir)(fd); |
| 170 if (windows) { |
| 171 // TODO(smklein) Update this once fchdir is implemented. |
| 172 ASSERT_NE_MSG(retcode, 0, "fchdir() should have failed"); |
| 173 return passed("test_fchdir", "all"); |
| 174 } else { |
| 175 ASSERT_EQ_MSG(retcode, 0, "fchdir() failed"); |
| 176 } |
| 177 |
| 178 rtn = getcwd(newdir, PATH_MAX); |
| 179 ASSERT_EQ_MSG(rtn, newdir, "getcwd() failed"); |
| 180 |
| 181 ASSERT_MSG(strcmp(newdir, parent) == 0, "getcwd() failed after fchdir"); |
| 182 |
| 183 ASSERT_EQ_MSG(close(fd), 0, "close() failed"); |
| 184 |
| 185 // Let's go back to the child directory |
| 186 fd = open(dirname, O_RDONLY | O_DIRECTORY); |
| 187 ASSERT_NE_MSG(fd, -1, "open() failed to open child directory"); |
| 188 |
| 189 retcode = NACL_SYSCALL(fchdir)(fd); |
| 190 ASSERT_EQ_MSG(retcode, 0, "fchdir() failed"); |
| 191 |
| 192 rtn = getcwd(newdir, PATH_MAX); |
| 193 ASSERT_EQ_MSG(rtn, newdir, "getcwd() failed"); |
| 194 |
| 195 ASSERT_MSG(strcmp(newdir, dirname) == 0, "getcwd() failed after fchdir"); |
| 196 return passed("test fchdir", "all"); |
| 197 } |
| 198 |
| 140 bool test_mkdir_rmdir(const char *test_file) { | 199 bool test_mkdir_rmdir(const char *test_file) { |
| 141 // Use a temporary direcotry name alongside the test_file which | 200 // Use a temporary directory name alongside the test_file which |
| 142 // was passed in. | 201 // was passed in. |
| 143 char dirname[PATH_MAX]; | 202 char dirname[PATH_MAX]; |
| 144 strncpy(dirname, test_file, PATH_MAX); | 203 strncpy(dirname, test_file, PATH_MAX); |
| 145 split_name(dirname); | 204 split_name(dirname); |
| 146 | 205 |
| 147 ASSERT(strlen(dirname) + 6 < PATH_MAX); | 206 ASSERT(strlen(dirname) + 6 < PATH_MAX); |
| 148 strncat(dirname, "tmpdir", 6); | 207 strncat(dirname, "tmpdir", 6); |
| 149 | 208 |
| 150 // Attempt to remove the directory in case it already exists | 209 // Attempt to remove the directory in case it already exists |
| 151 // from a previous test run. | 210 // from a previous test run. |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 ensure_file_is_absent(target_filename); | 361 ensure_file_is_absent(target_filename); |
| 303 ensure_file_is_absent(link_filename); | 362 ensure_file_is_absent(link_filename); |
| 304 | 363 |
| 305 // Create link target with some dummy data | 364 // Create link target with some dummy data |
| 306 int fd = open(target_filename, O_WRONLY | O_CREAT, S_IRWXU); | 365 int fd = open(target_filename, O_WRONLY | O_CREAT, S_IRWXU); |
| 307 ASSERT(fd >= 0); | 366 ASSERT(fd >= 0); |
| 308 ASSERT_EQ(write(fd, "123", 3), 3); | 367 ASSERT_EQ(write(fd, "123", 3), 3); |
| 309 ASSERT_EQ(close(fd), 0); | 368 ASSERT_EQ(close(fd), 0); |
| 310 | 369 |
| 311 int rtn = link(target_filename, link_filename); | 370 int rtn = link(target_filename, link_filename); |
| 312 if (rtn != 0 && errno == ENOSYS) { | 371 if (rtn != 0 && errno == ENOSYS && windows) { |
| 313 // If we get ENOSYS, assume we are on Windows, where link() is expected | 372 // If we get ENOSYS, assume we are on Windows, where link() is expected |
| 314 // to fail. | 373 // to fail. |
| 315 return passed("test_link", "all"); | 374 return passed("test_link", "all"); |
| 316 } | 375 } |
| 317 ASSERT_EQ(rtn, 0); | 376 ASSERT_EQ(rtn, 0); |
| 318 | 377 |
| 319 // Verify that the new file is a regular file and that changes to it are | 378 // Verify that the new file is a regular file and that changes to it are |
| 320 // mirrored in the original file. | 379 // mirrored in the original file. |
| 321 ASSERT_EQ(stat(link_filename, &buf), 0); | 380 ASSERT_EQ(stat(link_filename, &buf), 0); |
| 322 ASSERT_EQ(stat(target_filename, &buf_orig), 0); | 381 ASSERT_EQ(stat(target_filename, &buf_orig), 0); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 // Split filename into basename and dirname. | 417 // Split filename into basename and dirname. |
| 359 strncpy(dirname, test_file, PATH_MAX); | 418 strncpy(dirname, test_file, PATH_MAX); |
| 360 char *basename = split_name(dirname); | 419 char *basename = split_name(dirname); |
| 361 | 420 |
| 362 snprintf(link_filename, PATH_MAX, "%s.link", test_file); | 421 snprintf(link_filename, PATH_MAX, "%s.link", test_file); |
| 363 | 422 |
| 364 ensure_file_is_absent(link_filename); | 423 ensure_file_is_absent(link_filename); |
| 365 | 424 |
| 366 // Create this link | 425 // Create this link |
| 367 int rtn = symlink(basename, link_filename); | 426 int rtn = symlink(basename, link_filename); |
| 368 if (rtn != 0 && errno == ENOSYS) { | 427 if (rtn != 0 && errno == ENOSYS && windows) { |
| 369 // If we get ENOSYS, assume we are on Windows, where symlink() and | 428 // If we get ENOSYS, assume we are on Windows, where symlink() and |
| 370 // readlink() are expected to fail. | 429 // readlink() are expected to fail. |
| 371 return passed("test_symlinks", "all"); | 430 return passed("test_symlinks", "all"); |
| 372 } | 431 } |
| 373 ASSERT_EQ(rtn, 0); | 432 ASSERT_EQ(rtn, 0); |
| 374 | 433 |
| 375 // Check the lstat() and stat of the link | 434 // Check the lstat() and stat of the link |
| 376 ASSERT_EQ(lstat(link_filename, &buf), 0); | 435 ASSERT_EQ(lstat(link_filename, &buf), 0); |
| 377 ASSERT_NE_MSG(S_ISLNK(buf.st_mode), 0, "lstat of link failed to be ISLNK"); | 436 ASSERT_NE_MSG(S_ISLNK(buf.st_mode), 0, "lstat of link failed to be ISLNK"); |
| 378 ASSERT_EQ_MSG(S_ISREG(buf.st_mode), 0, "lstat of link should not be ISREG"); | 437 ASSERT_EQ_MSG(S_ISREG(buf.st_mode), 0, "lstat of link should not be ISREG"); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 // change the file to readonly and verify the change | 481 // change the file to readonly and verify the change |
| 423 ASSERT_EQ(chmod(temp_file, S_IRUSR), 0); | 482 ASSERT_EQ(chmod(temp_file, S_IRUSR), 0); |
| 424 ASSERT_EQ(stat(temp_file, &buf), 0); | 483 ASSERT_EQ(stat(temp_file, &buf), 0); |
| 425 ASSERT_EQ(buf.st_mode & ~S_IFMT, S_IRUSR); | 484 ASSERT_EQ(buf.st_mode & ~S_IFMT, S_IRUSR); |
| 426 ASSERT(open(temp_file, O_WRONLY) < 0); | 485 ASSERT(open(temp_file, O_WRONLY) < 0); |
| 427 | 486 |
| 428 ASSERT_EQ(remove(temp_file), 0); | 487 ASSERT_EQ(remove(temp_file), 0); |
| 429 return passed("test_chmod", "all"); | 488 return passed("test_chmod", "all"); |
| 430 } | 489 } |
| 431 | 490 |
| 491 bool test_fchmod(const char *test_file) { |
| 492 struct stat buf; |
| 493 char temp_file[PATH_MAX]; |
| 494 int retcode; |
| 495 snprintf(temp_file, PATH_MAX, "%s.tmp_fchmod", test_file); |
| 496 |
| 497 int fd = open(temp_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); |
| 498 ASSERT(fd >= 0); |
| 499 |
| 500 ASSERT_EQ(stat(temp_file, &buf), 0); |
| 501 ASSERT_EQ(buf.st_mode & ~S_IFMT, S_IRUSR | S_IWUSR); |
| 502 |
| 503 // change the file to readonly and verify the change |
| 504 retcode = NACL_SYSCALL(fchmod)(fd, S_IRUSR); |
| 505 if (windows) { |
| 506 // TODO(smklein) Update this once fchmod is implemented. |
| 507 ASSERT_NE_MSG(retcode, 0, "fchmod() should have failed"); |
| 508 return passed("test_fchmod", "all"); |
| 509 } else { |
| 510 ASSERT_EQ(retcode, 0); |
| 511 } |
| 512 ASSERT_EQ(stat(temp_file, &buf), 0); |
| 513 ASSERT_EQ(buf.st_mode & ~S_IFMT, S_IRUSR); |
| 514 ASSERT(open(temp_file, O_WRONLY) < 0); |
| 515 |
| 516 ASSERT_EQ(close(fd), 0); |
| 517 ASSERT_EQ(remove(temp_file), 0); |
| 518 return passed("test_fchmod", "all"); |
| 519 } |
| 520 |
| 432 static void test_access_call(const char *path, int mode, int expected_result) { | 521 static void test_access_call(const char *path, int mode, int expected_result) { |
| 433 ASSERT_EQ(access(path, mode), expected_result); | 522 ASSERT_EQ(access(path, mode), expected_result); |
| 434 ASSERT_EQ(eaccess(path, mode), expected_result); | 523 ASSERT_EQ(eaccess(path, mode), expected_result); |
| 435 } | 524 } |
| 436 | 525 |
| 437 bool test_access(const char *test_file) { | 526 bool test_access(const char *test_file) { |
| 438 char temp_access[PATH_MAX]; | 527 char temp_access[PATH_MAX]; |
| 439 snprintf(temp_access, PATH_MAX, "%s.tmp_access", test_file); | 528 snprintf(temp_access, PATH_MAX, "%s.tmp_access", test_file); |
| 440 | 529 |
| 441 test_access_call(test_file, F_OK, 0); | 530 test_access_call(test_file, F_OK, 0); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 465 ASSERT_EQ(remove(temp_access), 0); | 554 ASSERT_EQ(remove(temp_access), 0); |
| 466 | 555 |
| 467 return passed("test_access", "all"); | 556 return passed("test_access", "all"); |
| 468 } | 557 } |
| 469 | 558 |
| 470 bool test_utimes(const char *test_file) { | 559 bool test_utimes(const char *test_file) { |
| 471 // TODO(mseaborn): Implement utimes for unsandboxed mode. | 560 // TODO(mseaborn): Implement utimes for unsandboxed mode. |
| 472 if (NONSFI_MODE) | 561 if (NONSFI_MODE) |
| 473 return true; | 562 return true; |
| 474 struct timeval times[2]; | 563 struct timeval times[2]; |
| 475 // utimes() is currently not implemented and should always | 564 // These numbers are close enough to the epoch time. Windows |
| 476 // fail with ENOSYS | 565 // does not like going back in time. |
| 477 ASSERT_EQ(utimes("dummy", times), -1); | 566 time_t a_sec = 2132067496; |
| 478 ASSERT_EQ(errno, ENOSYS); | 567 time_t m_sec = 2132067497; |
| 568 times[0].tv_sec = a_sec; |
| 569 times[0].tv_usec = 222; |
| 570 times[1].tv_sec = m_sec; |
| 571 times[1].tv_usec = 444; |
| 572 char temp_file[PATH_MAX]; |
| 573 snprintf(temp_file, PATH_MAX, "%s.tmp_utimes", test_file); |
| 574 ensure_file_is_absent(temp_file); |
| 575 |
| 576 int fd = open(temp_file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); |
| 577 ASSERT(fd >= 0); |
| 578 ASSERT_EQ(close(fd), 0); |
| 579 |
| 580 // Use the times we generated earlier (and check the second resolution) |
| 581 ASSERT_EQ(NACL_SYSCALL(utimes)(temp_file, times), 0); |
| 582 |
| 583 // Verify the actime + modtime. |
| 584 struct stat s; |
| 585 ASSERT_EQ(stat(temp_file, &s), 0); |
| 586 ASSERT_EQ(s.st_atime, a_sec); |
| 587 ASSERT_EQ(s.st_mtime, m_sec); |
| 588 |
| 589 // "NULL" should be a valid time. We only check error code status here. |
| 590 ASSERT_EQ(NACL_SYSCALL(utimes)(temp_file, NULL), 0); |
| 479 return passed("test_utimes", "all"); | 591 return passed("test_utimes", "all"); |
| 480 } | 592 } |
| 481 | 593 |
| 482 bool test_utime(const char *test_file) { | 594 bool test_fsync(const char *test_file) { |
| 483 // TODO(mseaborn): Implement utimes for unsandboxed mode. | 595 char temp_file[PATH_MAX]; |
| 484 if (NONSFI_MODE) | 596 snprintf(temp_file, PATH_MAX, "%s.tmp_fsync", test_file); |
| 485 return true; | |
| 486 printf("test_utime"); | |
| 487 struct utimbuf times; | |
| 488 times.actime = 0; | |
| 489 times.modtime = 0; | |
| 490 // utimes() is currently not implemented and should always | |
| 491 // fail with ENOSYS | |
| 492 printf("test_utime 2"); | |
| 493 | 597 |
| 494 ASSERT_EQ(utime("dummy", ×), -1); | 598 char buffer[100]; |
| 495 ASSERT_EQ(errno, ENOSYS); | 599 for (size_t i = 0; i < sizeof(buffer); i++) |
| 496 return passed("test_utime", "all"); | 600 buffer[i] = i; |
| 601 |
| 602 // Write 100 sequential chars to the test file. |
| 603 int fd = open(temp_file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); |
| 604 ASSERT(fd >= 0); |
| 605 ASSERT_EQ(100, write(fd, buffer, 100)); |
| 606 |
| 607 // For now, only testing that fsync does not return an error. |
| 608 // This is a weak test -- TODO(smklein) improve it. |
| 609 ASSERT_EQ(0, NACL_SYSCALL(fsync)(fd)); |
| 610 ASSERT_EQ(0, close(fd)); |
| 611 |
| 612 return passed("test_fsync", "all"); |
| 613 } |
| 614 |
| 615 bool test_fdatasync(const char *test_file) { |
| 616 char temp_file[PATH_MAX]; |
| 617 snprintf(temp_file, PATH_MAX, "%s.tmp_fdatasync", test_file); |
| 618 |
| 619 char buffer[100]; |
| 620 for (size_t i = 0; i < sizeof(buffer); i++) |
| 621 buffer[i] = i; |
| 622 |
| 623 // Write 100 sequential chars to the test file. |
| 624 int fd = open(temp_file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); |
| 625 ASSERT(fd >= 0); |
| 626 ASSERT_EQ(100, write(fd, buffer, 100)); |
| 627 |
| 628 // For now, only testing that fdatasync does not return an error. |
| 629 // This is a weak test -- TODO(smklein) improve it. |
| 630 ASSERT_EQ(0, NACL_SYSCALL(fdatasync)(fd)); |
| 631 ASSERT_EQ(0, close(fd)); |
| 632 |
| 633 return passed("test_fdatasync", "all"); |
| 497 } | 634 } |
| 498 | 635 |
| 499 bool test_truncate(const char *test_file) { | 636 bool test_truncate(const char *test_file) { |
| 500 char temp_file[PATH_MAX]; | 637 char temp_file[PATH_MAX]; |
| 501 snprintf(temp_file, PATH_MAX, "%s.tmp_truncate", test_file); | 638 snprintf(temp_file, PATH_MAX, "%s.tmp_truncate", test_file); |
| 502 | 639 |
| 503 char buffer[100]; | 640 char buffer[100]; |
| 504 char read_buffer[200]; | 641 char read_buffer[200]; |
| 505 struct stat buf; | 642 struct stat buf; |
| 506 for (size_t i = 0; i < sizeof(buffer); i++) | 643 for (size_t i = 0; i < sizeof(buffer); i++) |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 fd = open(temp_file, O_RDONLY); | 676 fd = open(temp_file, O_RDONLY); |
| 540 ASSERT(fd >= 0); | 677 ASSERT(fd >= 0); |
| 541 ASSERT_EQ(read(fd, read_buffer, 50), 50); | 678 ASSERT_EQ(read(fd, read_buffer, 50), 50); |
| 542 ASSERT_EQ(memcmp(read_buffer, buffer, 50), 0); | 679 ASSERT_EQ(memcmp(read_buffer, buffer, 50), 0); |
| 543 ASSERT_EQ(0, close(fd)); | 680 ASSERT_EQ(0, close(fd)); |
| 544 | 681 |
| 545 ASSERT_EQ(remove(temp_file), 0); | 682 ASSERT_EQ(remove(temp_file), 0); |
| 546 return passed("test_truncate", "all"); | 683 return passed("test_truncate", "all"); |
| 547 } | 684 } |
| 548 | 685 |
| 686 bool test_ftruncate(const char *test_file) { |
| 687 char temp_file[PATH_MAX]; |
| 688 snprintf(temp_file, PATH_MAX, "%s.tmp_ftruncate", test_file); |
| 689 |
| 690 char buffer[100]; |
| 691 char read_buffer[200]; |
| 692 struct stat buf; |
| 693 for (size_t i = 0; i < sizeof(buffer); i++) |
| 694 buffer[i] = i; |
| 695 |
| 696 // Write 100 sequential chars to the test file. |
| 697 int fd = open(temp_file, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); |
| 698 ASSERT(fd >= 0); |
| 699 ASSERT_EQ(100, write(fd, buffer, 100)); |
| 700 |
| 701 ASSERT_EQ(0, close(fd)); |
| 702 fd = open(temp_file, O_WRONLY, S_IRUSR | S_IWUSR); |
| 703 ASSERT_EQ(stat(temp_file, &buf), 0); |
| 704 ASSERT_EQ(buf.st_size, 100); |
| 705 |
| 706 // ftruncate the file beyond its current length |
| 707 ASSERT_EQ(NACL_SYSCALL(ftruncate)(fd, 200), 0); |
| 708 ASSERT_EQ(0, close(fd)); |
| 709 ASSERT_EQ(stat(temp_file, &buf), 0); |
| 710 ASSERT_EQ(buf.st_size, 200); |
| 711 |
| 712 // Verify the new content, which should not be 100 |
| 713 // bytes of sequential chars and 100 bytes of '\0' |
| 714 fd = open(temp_file, O_RDWR); |
| 715 ASSERT(fd >= 0); |
| 716 ASSERT_EQ(read(fd, read_buffer, 200), 200); |
| 717 ASSERT_EQ(memcmp(read_buffer, buffer, 100), 0); |
| 718 for (int i = 100; i < 200; i++) |
| 719 ASSERT_EQ(read_buffer[i], 0); |
| 720 |
| 721 // Now ftruncate the file to a size smaller than the |
| 722 // original |
| 723 ASSERT_EQ(NACL_SYSCALL(ftruncate)(fd, 50), 0); |
| 724 ASSERT_EQ(0, close(fd)); |
| 725 ASSERT_EQ(stat(temp_file, &buf), 0); |
| 726 ASSERT_EQ(buf.st_size, 50); |
| 727 |
| 728 fd = open(temp_file, O_RDONLY); |
| 729 ASSERT(fd >= 0); |
| 730 ASSERT_EQ(read(fd, read_buffer, 50), 50); |
| 731 ASSERT_EQ(memcmp(read_buffer, buffer, 50), 0); |
| 732 ASSERT_EQ(0, close(fd)); |
| 733 |
| 734 ASSERT_EQ(remove(temp_file), 0); |
| 735 return passed("test_ftruncate", "all"); |
| 736 } |
| 737 |
| 738 |
| 549 bool test_open_trunc(const char *test_file) { | 739 bool test_open_trunc(const char *test_file) { |
| 550 int fd; | 740 int fd; |
| 551 char buffer[100]; | 741 char buffer[100]; |
| 552 struct stat buf; | 742 struct stat buf; |
| 553 const char *testname = "test_open_trunc"; | 743 const char *testname = "test_open_trunc"; |
| 554 char temp_file[PATH_MAX]; | 744 char temp_file[PATH_MAX]; |
| 555 snprintf(temp_file, PATH_MAX, "%s.open_truncate", test_file); | 745 snprintf(temp_file, PATH_MAX, "%s.open_truncate", test_file); |
| 556 | 746 |
| 557 // Write some data to a new file. | 747 // Write some data to a new file. |
| 558 fd = open(temp_file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); | 748 fd = open(temp_file, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); |
| (...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 ret &= test_read(test_file); | 1359 ret &= test_read(test_file); |
| 1170 ret &= test_write(test_file); | 1360 ret &= test_write(test_file); |
| 1171 ret &= test_lseek(test_file); | 1361 ret &= test_lseek(test_file); |
| 1172 ret &= test_readdir(test_file); | 1362 ret &= test_readdir(test_file); |
| 1173 ret &= test_gethostname(); | 1363 ret &= test_gethostname(); |
| 1174 // glibc support for calling syscalls directly, without the IRT, is limited | 1364 // glibc support for calling syscalls directly, without the IRT, is limited |
| 1175 // so we skip certain tests in this case. | 1365 // so we skip certain tests in this case. |
| 1176 #if !defined(__GLIBC__) || TESTS_USE_IRT | 1366 #if !defined(__GLIBC__) || TESTS_USE_IRT |
| 1177 ret &= test_unlink(test_file); | 1367 ret &= test_unlink(test_file); |
| 1178 ret &= test_chdir(); | 1368 ret &= test_chdir(); |
| 1179 ret &= test_mkdir_rmdir(test_file); | 1369 ret &= test_fchdir(); |
| 1180 ret &= test_getcwd(); | 1370 ret &= test_getcwd(); |
| 1181 ret &= test_mkdir_rmdir(test_file); | 1371 ret &= test_mkdir_rmdir(test_file); |
| 1182 ret &= test_isatty(test_file); | 1372 ret &= test_isatty(test_file); |
| 1183 ret &= test_rename(test_file); | 1373 ret &= test_rename(test_file); |
| 1184 ret &= test_link(test_file); | 1374 ret &= test_link(test_file); |
| 1185 ret &= test_symlinks(test_file); | 1375 ret &= test_symlinks(test_file); |
| 1186 ret &= test_chmod(test_file); | 1376 ret &= test_chmod(test_file); |
| 1377 ret &= test_fchmod(test_file); |
| 1187 ret &= test_access(test_file); | 1378 ret &= test_access(test_file); |
| 1379 ret &= test_fsync(test_file); |
| 1380 ret &= test_fdatasync(test_file); |
| 1381 ret &= test_utimes(test_file); |
| 1188 #endif | 1382 #endif |
| 1189 // TODO(sbc): remove this restriction once glibc's truncate calls | 1383 // TODO(sbc): remove this restriction once glibc's truncate calls |
| 1190 // is hooked up to the IRT dev-filename-0.2 interface: | 1384 // is hooked up to the IRT dev-filename-0.2 interface: |
| 1191 // https://code.google.com/p/nativeclient/issues/detail?id=3709 | 1385 // https://code.google.com/p/nativeclient/issues/detail?id=3709 |
| 1192 #if !(defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 9) | 1386 #if !(defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 9) |
| 1193 ret &= test_truncate(test_file); | 1387 ret &= test_truncate(test_file); |
| 1388 ret &= test_ftruncate(test_file); |
| 1194 #endif | 1389 #endif |
| 1195 ret &= test_utimes(test_file); | |
| 1196 ret &= test_utime(test_file); | |
| 1197 return ret; | 1390 return ret; |
| 1198 } | 1391 } |
| 1199 | 1392 |
| 1200 /* | 1393 /* |
| 1201 * main entry point. | 1394 * main entry point. |
| 1202 * | 1395 * |
| 1203 * run all tests and call system exit with appropriate value | 1396 * run all tests and call system exit with appropriate value |
| 1204 * 0 - success, all tests passed. | 1397 * 0 - success, all tests passed. |
| 1205 * -1 - one or more tests failed. | 1398 * -1 - one or more tests failed. |
| 1206 */ | 1399 */ |
| 1207 | 1400 |
| 1208 int main(const int argc, const char *argv[]) { | 1401 int main(const int argc, const char *argv[]) { |
| 1209 bool passed; | 1402 bool passed; |
| 1210 | 1403 |
| 1211 if (argc != 2) { | 1404 if (argc != 3) { |
| 1212 printf("Please specify the test file name\n"); | 1405 printf("Please specify the test file name\n"); |
| 1213 exit(-1); | 1406 exit(-1); |
| 1214 } | 1407 } |
| 1408 if (argv[2][0] == 'w') { |
| 1409 windows = true; |
| 1410 } |
| 1215 // run the full test suite | 1411 // run the full test suite |
| 1216 passed = testSuite(argv[1]); | 1412 passed = testSuite(argv[1]); |
| 1217 | 1413 |
| 1218 if (passed) { | 1414 if (passed) { |
| 1219 printf("All tests PASSED\n"); | 1415 printf("All tests PASSED\n"); |
| 1220 exit(0); | 1416 exit(0); |
| 1221 } else { | 1417 } else { |
| 1222 printf("One or more tests FAILED\n"); | 1418 printf("One or more tests FAILED\n"); |
| 1223 exit(-1); | 1419 exit(-1); |
| 1224 } | 1420 } |
| 1225 } | 1421 } |
| OLD | NEW |