helpers.c 2.7KB

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