read_file.h 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /**
  2. * @file read_file.h
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * This file is part of BadVPN.
  8. *
  9. * BadVPN is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * BadVPN is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. *
  22. * @section DESCRIPTION
  23. *
  24. * Function for reading a file into memory using stdio.
  25. */
  26. #ifndef BADVPN_MISC_READ_FILE_H
  27. #define BADVPN_MISC_READ_FILE_H
  28. #include <stddef.h>
  29. #include <stdint.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. static int read_file (const char *file, uint8_t **out_data, size_t *out_len)
  33. {
  34. FILE *f = fopen(file, "r");
  35. if (!f) {
  36. goto fail0;
  37. }
  38. size_t buf_len = 0;
  39. size_t buf_size = 128;
  40. uint8_t *buf = malloc(buf_size);
  41. if (!buf) {
  42. goto fail1;
  43. }
  44. while (1) {
  45. if (buf_len == buf_size) {
  46. if (2 > SIZE_MAX / buf_size) {
  47. goto fail;
  48. }
  49. size_t newsize = 2 * buf_size;
  50. uint8_t *newbuf = realloc(buf, newsize);
  51. if (!newbuf) {
  52. goto fail;
  53. }
  54. buf = newbuf;
  55. buf_size = newsize;
  56. }
  57. size_t bytes = fread(buf + buf_len, 1, buf_size - buf_len, f);
  58. if (bytes == 0) {
  59. if (feof(f)) {
  60. break;
  61. }
  62. goto fail;
  63. }
  64. buf_len += bytes;
  65. }
  66. fclose(f);
  67. *out_data = buf;
  68. *out_len = buf_len;
  69. return 1;
  70. fail:
  71. free(buf);
  72. fail1:
  73. fclose(f);
  74. fail0:
  75. return 0;
  76. }
  77. #endif