proc-net-dev-lseek.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /*
  2. * Copyright (c) 2025 Alexey Dobriyan <adobriyan@gmail.com>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #undef _GNU_SOURCE
  17. #define _GNU_SOURCE
  18. #undef NDEBUG
  19. #include <assert.h>
  20. #include <errno.h>
  21. #include <fcntl.h>
  22. #include <string.h>
  23. #include <unistd.h>
  24. #include <sched.h>
  25. /*
  26. * Test that lseek("/proc/net/dev/", 0, SEEK_SET)
  27. * a) works,
  28. * b) does what you think it does.
  29. */
  30. int main(void)
  31. {
  32. /* /proc/net/dev output is deterministic in fresh netns only. */
  33. if (unshare(CLONE_NEWNET) == -1) {
  34. if (errno == ENOSYS || errno == EPERM) {
  35. return 4;
  36. }
  37. return 1;
  38. }
  39. const int fd = open("/proc/net/dev", O_RDONLY);
  40. assert(fd >= 0);
  41. char buf1[4096];
  42. const ssize_t rv1 = read(fd, buf1, sizeof(buf1));
  43. /*
  44. * Not "<=", this file can't be empty:
  45. * there is header, "lo" interface with some zeroes.
  46. */
  47. assert(0 < rv1);
  48. assert(rv1 <= sizeof(buf1));
  49. /* Believe it or not, this line broke one day. */
  50. assert(lseek(fd, 0, SEEK_SET) == 0);
  51. char buf2[4096];
  52. const ssize_t rv2 = read(fd, buf2, sizeof(buf2));
  53. /* Not "<=", see above. */
  54. assert(0 < rv2);
  55. assert(rv2 <= sizeof(buf2));
  56. /* Test that lseek rewinds to the beginning of the file. */
  57. assert(rv1 == rv2);
  58. assert(memcmp(buf1, buf2, rv1) == 0);
  59. /* Contents of the file is not validated: this test is about lseek(). */
  60. return 0;
  61. }