common.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "common.h"
  2. noreturn void fatal_error(const char* fmt, ...) {
  3. va_list args;
  4. va_start(args, fmt);
  5. fprintf(stderr, "ERROR: ");
  6. vfprintf(stderr, fmt, args);
  7. va_end(args);
  8. exit(-1);
  9. }
  10. void setup() {
  11. // set output to line-buffered for easier debugging
  12. setvbuf(stdout, NULL, _IOLBF, 0);
  13. setvbuf(stderr, NULL, _IOLBF, 0);
  14. unsigned int seed = time(NULL);
  15. printf("Random seed: %u\n", seed);
  16. srand(seed);
  17. }
  18. int open_input_fd(const char* path) {
  19. int fd = open(path, O_RDONLY);
  20. if (fd < 0)
  21. fatal_error("Failed to open input file %s: %s\n", path, strerror(errno));
  22. return fd;
  23. }
  24. void read_fd(const char* path, int fd, void* buffer, size_t size) {
  25. off_t offset = 0;
  26. while (size > 0) {
  27. ssize_t ret = read(fd, buffer + offset, size);
  28. if (ret == -EINTR)
  29. continue;
  30. if (ret <= 0)
  31. fatal_error("Failed to read file %s: %s\n", path, strerror(errno));
  32. size -= ret;
  33. offset += ret;
  34. }
  35. }
  36. void seek_fd(const char* path, int fd, ssize_t offset, int mode) {
  37. off_t ret = lseek(fd, offset, mode);
  38. if (ret == -1)
  39. fatal_error("Failed to lseek(%zd, %d) file %s: %s\n", offset, mode, path, strerror(errno));
  40. }
  41. off_t tell_fd(const char* path, int fd) {
  42. off_t pos = lseek(fd, 0, SEEK_CUR);
  43. if (pos == -1)
  44. fatal_error("Failed to lseek(0, SEEK_CUR) file %s: %s\n", path, strerror(errno));
  45. return pos;
  46. }
  47. int open_output_fd(const char* path, bool rdwr) {
  48. int fd = open(path, rdwr ? O_RDWR|O_CREAT : O_WRONLY|O_CREAT, 0664);
  49. if (fd < 0)
  50. fatal_error("Failed to open output file %s: %s\n", path, strerror(errno));
  51. return fd;
  52. }
  53. void write_fd(const char* path, int fd, const void* buffer, size_t size) {
  54. off_t offset = 0;
  55. while (size > 0) {
  56. ssize_t ret = write(fd, buffer + offset, size);
  57. if (ret == -EINTR)
  58. continue;
  59. if (ret <= 0)
  60. fatal_error("Failed to write file %s: %s\n", path, strerror(errno));
  61. size -= ret;
  62. offset += ret;
  63. }
  64. }
  65. void close_fd(const char* path, int fd) {
  66. if (fd >= 0 && close(fd) != 0)
  67. fatal_error("Failed to close file %s: %s\n", path, strerror(errno));
  68. }
  69. void* mmap_fd(const char* path, int fd, int protection, size_t offset, size_t size) {
  70. void* address = mmap(NULL, size, protection, MAP_SHARED, fd, offset);
  71. if (address == MAP_FAILED)
  72. fatal_error("Failed to mmap file %s: %s\n", path, strerror(errno));
  73. return address;
  74. }
  75. void munmap_fd(const char* path, void* address, size_t size) {
  76. if (munmap(address, size) < 0)
  77. fatal_error("Failed to munmap file %s: %s\n", path, strerror(errno));
  78. }
  79. FILE* open_input_stdio(const char* path) {
  80. FILE* f = fopen(path, "r");
  81. if (!f)
  82. fatal_error("Failed to fopen input file %s: %s\n", path, strerror(errno));
  83. return f;
  84. }
  85. void read_stdio(const char* path, FILE* f, void* buffer, size_t size) {
  86. if (size > 0) {
  87. size_t ret = fread(buffer, size, 1, f);
  88. if (ret != 1)
  89. fatal_error("Failed to fread file %s: %s\n", path, strerror(errno));
  90. }
  91. }
  92. void seek_stdio(const char* path, FILE* f, off_t offset, int mode) {
  93. if (offset > LONG_MAX)
  94. fatal_error("Failed to fseek file %s(%zd): offset too big\n", path, offset);
  95. int ret = fseek(f, (long)offset, mode);
  96. if (ret < 0)
  97. fatal_error("Failed to fseek file %s(%zd): %s\n", path, offset, strerror(errno));
  98. }
  99. off_t tell_stdio(const char* path, FILE* f) {
  100. long pos = ftell(f);
  101. if (pos < 0)
  102. fatal_error("Failed to ftell file %s: %s\n", path, strerror(errno));
  103. return pos;
  104. }
  105. void close_stdio(const char* path, FILE* f) {
  106. if (f && fclose(f) != 0)
  107. fatal_error("Failed to fclose file %s: %s\n", path, strerror(errno));
  108. }
  109. FILE* open_output_stdio(const char* path, bool rdwr) {
  110. FILE* f = fopen(path, rdwr ? "r+" : "w");
  111. if (!f)
  112. fatal_error("Failed to fopen output file %s: %s\n", path, strerror(errno));
  113. return f;
  114. }
  115. void write_stdio(const char* path, FILE* f, const void* buffer, size_t size) {
  116. if (size > 0) {
  117. size_t ret = fwrite(buffer, size, 1, f);
  118. if (ret != 1)
  119. fatal_error("Failed to fwrite file %s: %s\n", path, strerror(errno));
  120. }
  121. }
  122. void* alloc_buffer(size_t size) {
  123. void* buffer = malloc(size);
  124. if (!buffer)
  125. fatal_error("No memory\n");
  126. return buffer;
  127. }
  128. void fill_random(void* buffer, size_t size) {
  129. for (size_t i = 0; i < size; i++)
  130. ((uint8_t*)buffer)[i] = rand() % 256;
  131. }