mmap-file.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #define _GNU_SOURCE
  2. #include <signal.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <sys/mman.h>
  6. #include <sys/types.h>
  7. #include <sys/wait.h>
  8. #include <unistd.h>
  9. static const char* message;
  10. void SIGBUS_handler(int sig) {
  11. puts(message);
  12. exit(0);
  13. }
  14. int main(int argc, const char** argv) {
  15. int rv;
  16. /* Initalization: create a 1025-byte file */
  17. FILE* fp = fopen("testfile", "w+");
  18. if (!fp) {
  19. perror("fopen");
  20. return 1;
  21. }
  22. rv = ftruncate(fileno(fp), 1024);
  23. if (rv) {
  24. perror("ftruncate");
  25. return 1;
  26. }
  27. volatile unsigned char* a =
  28. mmap(NULL, 9162, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FILE, fileno(fp), 0);
  29. if (a == MAP_FAILED) {
  30. perror("mmap");
  31. return 1;
  32. }
  33. a[1023] = 0xff;
  34. a[4095] = 0xff;
  35. __asm__ volatile ("nop" ::: "memory");
  36. int pid = fork();
  37. if (pid == -1) {
  38. perror("fork");
  39. return 1;
  40. }
  41. if (pid != 0) {
  42. rv = waitpid(pid, NULL, 0);
  43. if (rv == -1) {
  44. perror("waitpid");
  45. return 1;
  46. }
  47. }
  48. __asm__ volatile ("nop" ::: "memory");
  49. a[0] = 0xff;
  50. printf(pid == 0 ? "mmap test 1 passed\n" : "mmap test 6 passed\n");
  51. a[1024] = 0xff;
  52. printf(pid == 0 ? "mmap test 2 passed\n" : "mmap test 7 passed\n");
  53. __asm__ volatile ("nop" ::: "memory");
  54. if (pid == 0) {
  55. if (a[1023] == 0xff)
  56. printf("mmap test 3 passed\n");
  57. if (a[4095] == 0xff)
  58. printf("mmap test 4 passed\n");
  59. }
  60. __asm__ volatile ("nop" ::: "memory");
  61. if (signal(SIGBUS, SIGBUS_handler) == SIG_ERR) {
  62. perror("signal");
  63. return 1;
  64. }
  65. message = pid == 0 ? "mmap test 5 passed\n" : "mmap test 8 passed\n";
  66. /* need a barrier to assign message before SIGBUS due to a[4096] */
  67. __asm__ volatile ("nop" ::: "memory");
  68. a[4096] = 0xff;
  69. if (signal(SIGBUS, SIG_DFL) == SIG_ERR) {
  70. perror("signal");
  71. return 1;
  72. }
  73. return 0;
  74. }