Various modules solving daily C developer tasks
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
2.6 KiB

  1. /******************************************************************************
  2. *
  3. * Copyright (c) 2017-2019 by Löwenware Ltd
  4. * Please, refer LICENSE file for legal information
  5. *
  6. ******************************************************************************/
  7. /**
  8. * @file file.c
  9. * @author Ilja Kartašov <ik@lowenware.com>
  10. * @brief
  11. *
  12. * @see https://lowenware.com/
  13. */
  14. #include <stdio.h>
  15. #include <sys/sendfile.h>
  16. #include <fcntl.h>
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <errno.h>
  20. #include <string.h>
  21. #include <sys/stat.h>
  22. #include "file.h"
  23. bool
  24. cstuff_file_exists(const char *file)
  25. {
  26. return ( access( file, F_OK ) != -1 ) ? true : false;
  27. }
  28. CStuffRetcode
  29. cstuff_file_copy(const char *src, const char *dest)
  30. {
  31. CStuffRetcode rc = CSTUFF_SYSCALL_ERROR;
  32. int fd_src = open(src, O_RDWR), fd_dest, len;
  33. struct stat src_stat;
  34. if (!(fd_src < 0)) {
  35. if (lockf(fd_src, F_LOCK, 0) != -1) {
  36. if (!stat(src, &src_stat)) {
  37. fd_dest = open(dest, O_CREAT | O_WRONLY | O_TRUNC);
  38. if (!(fd_dest < 0)) {
  39. len = sendfile(fd_dest, fd_src, NULL, src_stat.st_size);
  40. if (len == src_stat.st_size) {
  41. rc = CSTUFF_SUCCESS;
  42. } else {
  43. fprintf(stderr, "sendfile error (%d != %d): %s\n", len,
  44. (int)src_stat.st_size, strerror(errno));
  45. }
  46. close(fd_dest);
  47. } else {
  48. fprintf(stderr, "dest open() error\n");
  49. }
  50. } else {
  51. fprintf(stderr, "src stat() error\n");
  52. }
  53. if (lockf(fd_src, F_TEST, 0) == 0){
  54. lockf(fd_src, F_ULOCK, 0);
  55. }
  56. } else {
  57. fprintf(stderr, "src lockf() error\n");
  58. }
  59. close(fd_src);
  60. } else {
  61. fprintf(stderr, "src open() error\n");
  62. }
  63. return rc;
  64. }
  65. CStuffRetcode
  66. cstuff_file_move(const char *src, const char *dest)
  67. {
  68. CStuffRetcode rc;
  69. if (!(rc = cstuff_file_copy(src, dest))) {
  70. if (unlink(src) != 0)
  71. return CSTUFF_SYSCALL_ERROR;
  72. }
  73. return rc;
  74. }
  75. CStuffRetcode
  76. cstuff_file_get_lines(const char *src, CStuffFileGetLine get_line, void *ctx)
  77. {
  78. FILE *f = NULL;
  79. size_t sz = 256;
  80. char *line;
  81. ssize_t rs;
  82. CStuffRetcode result = CSTUFF_SUCCESS;
  83. if (!(line = malloc(sz)))
  84. goto e_malloc;
  85. if (!(f = fopen(src, "r")))
  86. goto e_syscall;
  87. while ((rs = getdelim(&line, &sz, '\n', f)) != -1) {
  88. if (!get_line(line, rs, ctx)) {
  89. continue;
  90. } else {
  91. goto e_input;
  92. }
  93. }
  94. switch(errno) {
  95. case 0:
  96. break;
  97. case ENOMEM:
  98. goto e_malloc;
  99. default:
  100. goto e_syscall;
  101. }
  102. goto finally;
  103. e_input:
  104. result = CSTUFF_INPUT_ERROR;
  105. goto finally;
  106. e_malloc:
  107. result = CSTUFF_MALLOC_ERROR;
  108. goto finally;
  109. e_syscall:
  110. result = CSTUFF_SYSCALL_ERROR;
  111. goto finally;
  112. finally:
  113. if (line)
  114. free(line);
  115. if (f)
  116. fclose(f);
  117. return result;
  118. }