unix-file.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010-2018 Andy Green <[email protected]>
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation:
  9. * version 2.1 of the License.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  19. * MA 02110-1301 USA
  20. */
  21. #define _GNU_SOURCE
  22. #include "core/private.h"
  23. #include <pwd.h>
  24. #include <grp.h>
  25. #ifdef LWS_WITH_PLUGINS
  26. #include <dlfcn.h>
  27. #endif
  28. #include <dirent.h>
  29. int lws_plat_apply_FD_CLOEXEC(int n)
  30. {
  31. if (n == -1)
  32. return 0;
  33. return fcntl(n, F_SETFD, FD_CLOEXEC);
  34. }
  35. int
  36. lws_plat_write_file(const char *filename, void *buf, int len)
  37. {
  38. int m, fd;
  39. fd = lws_open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
  40. if (fd == -1)
  41. return 1;
  42. m = write(fd, buf, len);
  43. close(fd);
  44. return m != len;
  45. }
  46. int
  47. lws_plat_read_file(const char *filename, void *buf, int len)
  48. {
  49. int n, fd = lws_open(filename, O_RDONLY);
  50. if (fd == -1)
  51. return -1;
  52. n = read(fd, buf, len);
  53. close(fd);
  54. return n;
  55. }
  56. lws_fop_fd_t
  57. _lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename,
  58. const char *vpath, lws_fop_flags_t *flags)
  59. {
  60. struct stat stat_buf;
  61. int ret = lws_open(filename, (*flags) & LWS_FOP_FLAGS_MASK, 0664);
  62. lws_fop_fd_t fop_fd;
  63. if (ret < 0)
  64. return NULL;
  65. if (fstat(ret, &stat_buf) < 0)
  66. goto bail;
  67. fop_fd = malloc(sizeof(*fop_fd));
  68. if (!fop_fd)
  69. goto bail;
  70. fop_fd->fops = fops;
  71. fop_fd->flags = *flags;
  72. fop_fd->fd = ret;
  73. fop_fd->filesystem_priv = NULL; /* we don't use it */
  74. fop_fd->len = stat_buf.st_size;
  75. fop_fd->pos = 0;
  76. return fop_fd;
  77. bail:
  78. close(ret);
  79. return NULL;
  80. }
  81. int
  82. _lws_plat_file_close(lws_fop_fd_t *fop_fd)
  83. {
  84. int fd = (*fop_fd)->fd;
  85. free(*fop_fd);
  86. *fop_fd = NULL;
  87. return close(fd);
  88. }
  89. lws_fileofs_t
  90. _lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset)
  91. {
  92. lws_fileofs_t r;
  93. if (offset > 0 &&
  94. offset > (lws_fileofs_t)fop_fd->len - (lws_fileofs_t)fop_fd->pos)
  95. offset = fop_fd->len - fop_fd->pos;
  96. if ((lws_fileofs_t)fop_fd->pos + offset < 0)
  97. offset = -fop_fd->pos;
  98. r = lseek(fop_fd->fd, offset, SEEK_CUR);
  99. if (r >= 0)
  100. fop_fd->pos = r;
  101. else
  102. lwsl_err("error seeking from cur %ld, offset %ld\n",
  103. (long)fop_fd->pos, (long)offset);
  104. return r;
  105. }
  106. int
  107. _lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
  108. uint8_t *buf, lws_filepos_t len)
  109. {
  110. long n;
  111. n = read((int)fop_fd->fd, buf, len);
  112. if (n == -1) {
  113. *amount = 0;
  114. return -1;
  115. }
  116. fop_fd->pos += n;
  117. lwsl_debug("%s: read %ld of req %ld, pos %ld, len %ld\n", __func__, n,
  118. (long)len, (long)fop_fd->pos, (long)fop_fd->len);
  119. *amount = n;
  120. return 0;
  121. }
  122. int
  123. _lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount,
  124. uint8_t *buf, lws_filepos_t len)
  125. {
  126. long n;
  127. n = write((int)fop_fd->fd, buf, len);
  128. if (n == -1) {
  129. *amount = 0;
  130. return -1;
  131. }
  132. fop_fd->pos += n;
  133. *amount = n;
  134. return 0;
  135. }