readoffset.c 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #include <u.h>
  2. #include <libc.h>
  3. // Based on TestReadAtOffset in go's test suite.
  4. // Plan 9 pread had a bug where the channel offset we updated during a call to
  5. // pread - this shouldn't have happened.
  6. static char *tmpfilename = nil;
  7. static void
  8. rmtmp(void)
  9. {
  10. remove(tmpfilename);
  11. }
  12. static int
  13. preadn(int fd, char *buf, int32_t nbytes, int64_t offset)
  14. {
  15. int nread = 0;
  16. do {
  17. int n = pread(fd, buf, nbytes, offset);
  18. if (n == 0) {
  19. break;
  20. }
  21. buf += n;
  22. nbytes -= n;
  23. offset += n;
  24. nread += n;
  25. } while (nbytes > 0);
  26. return nread;
  27. }
  28. void
  29. main(int argc, char *argv[])
  30. {
  31. tmpfilename = mktemp("readoffset");
  32. int fd = create(tmpfilename, ORDWR, 0666);
  33. if (fd < 0) {
  34. print("FAIL: couldn't create file: %s\n", tmpfilename);
  35. exits("FAIL");
  36. }
  37. atexit(rmtmp);
  38. const char *data = "hello, world\n";
  39. write(fd, data, strlen(data));
  40. seek(fd, 0, 0);
  41. int n = 0;
  42. char b[5] = {0};
  43. int bsz = sizeof(b);
  44. n = preadn(fd, b, bsz, 7);
  45. if (n != sizeof(b)) {
  46. print("FAIL: unexpected number of bytes pread: %d (expected %d)\n", n, bsz);
  47. exits("FAIL");
  48. }
  49. if (strncmp(b, "world", 5) != 0) {
  50. print("FAIL: unexpected string pread: '%s'\n", b);
  51. exits("FAIL");
  52. }
  53. n = read(fd, b, bsz);
  54. if (n != sizeof(b)) {
  55. print("FAIL: unexpected number of bytes read: %d (expected %d)\n", n, bsz);
  56. exits("FAIL");
  57. }
  58. if (strncmp(b, "hello", 5) != 0) {
  59. print("FAIL: unexpected string read: '%s'\n", b);
  60. exits("FAIL");
  61. }
  62. print("PASS\n");
  63. exits(nil);
  64. }