helpers.c 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "helpers.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <dirent.h>
  7. #include <errno.h> // errno
  8. #include <libgen.h> // dirname
  9. bool light_file_read_uint64(char const *filename, uint64_t *val)
  10. {
  11. FILE *fp;
  12. uint64_t data;
  13. fp = fopen(filename, "r");
  14. if (!fp)
  15. {
  16. LIGHT_PERMERR("reading");
  17. return false;
  18. }
  19. if (fscanf(fp, "%lu", &data) != 1)
  20. {
  21. LIGHT_ERR("Couldn't parse an unsigned integer from '%s'", filename);
  22. fclose(fp);
  23. return false;
  24. }
  25. *val = data;
  26. fclose(fp);
  27. return true;
  28. }
  29. bool light_file_write_uint64(char const *filename, uint64_t val)
  30. {
  31. FILE *fp;
  32. fp = fopen(filename, "w");
  33. if (!fp)
  34. {
  35. LIGHT_PERMERR("writing");
  36. return false;
  37. }
  38. if (fprintf(fp, "%lu", val) < 0)
  39. {
  40. LIGHT_ERR("fprintf failed");
  41. fclose(fp);
  42. return false;
  43. }
  44. fclose(fp);
  45. return true;
  46. }
  47. /* Returns true if file is writable, false otherwise */
  48. bool light_file_is_writable(char const *filename)
  49. {
  50. FILE *fp;
  51. fp = fopen(filename, "r+");
  52. if (!fp)
  53. {
  54. LIGHT_PERMWARN("writing");
  55. return false;
  56. }
  57. fclose(fp);
  58. return true;
  59. }
  60. /* Returns true if file is readable, false otherwise */
  61. bool light_file_is_readable(char const *filename)
  62. {
  63. FILE *fp;
  64. fp = fopen(filename, "r");
  65. if (!fp)
  66. {
  67. LIGHT_PERMWARN("reading");
  68. return false;
  69. }
  70. fclose(fp);
  71. return true;
  72. }
  73. /* Prints a notice about a value which was below `x` and was adjusted to it */
  74. uint64_t light_log_clamp_min(uint64_t min)
  75. {
  76. LIGHT_NOTE("too small value, adjusting to mininum %lu (raw)", min);
  77. return min;
  78. }
  79. /* Prints a notice about a value which was above `x` and was adjusted to it */
  80. uint64_t light_log_clamp_max(uint64_t max)
  81. {
  82. LIGHT_NOTE("too large value, adjusting to mavalimum %lu (raw)", max);
  83. return max;
  84. }
  85. /* Clamps the `percent` value between 0% and 100% */
  86. double light_percent_clamp(double val)
  87. {
  88. if (val < 0.0)
  89. {
  90. LIGHT_WARN("specified value %g%% is not valid, adjusting it to 0%%", val);
  91. return 0.0;
  92. }
  93. if (val > 100.0)
  94. {
  95. LIGHT_WARN("specified value %g%% is not valid, adjusting it to 100%%", val);
  96. return 100.0;
  97. }
  98. return val;
  99. }
  100. int light_mkpath(char *dir, mode_t mode)
  101. {
  102. struct stat sb;
  103. if (!dir)
  104. {
  105. errno = EINVAL;
  106. return -1;
  107. }
  108. if (!stat(dir, &sb))
  109. return 0;
  110. char *tempdir = strdup(dir);
  111. light_mkpath(dirname(tempdir), mode);
  112. free(tempdir);
  113. return mkdir(dir, mode);
  114. }