1/* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25#if !defined(_GNU_SOURCE) 26#define _GNU_SOURCE 27#endif 28#include "private-lib-core.h" 29 30#include <pwd.h> 31#include <grp.h> 32 33#ifdef LWS_WITH_PLUGINS 34#include <dlfcn.h> 35#endif 36#include <dirent.h> 37 38int lws_plat_apply_FD_CLOEXEC(int n) 39{ 40 if (n == -1) 41 return 0; 42 43 return fcntl(n, F_SETFD, FD_CLOEXEC); 44} 45 46int 47lws_plat_write_file(const char *filename, void *buf, size_t len) 48{ 49 ssize_t m; 50 int fd; 51 52 fd = lws_open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 53 54 if (fd == -1) 55 return 1; 56 57 m = write(fd, buf, len); 58 close(fd); 59 60 if (m < 0) 61 return 1; 62 63 return (size_t)m != len; 64} 65 66int 67lws_plat_read_file(const char *filename, void *buf, size_t len) 68{ 69 int fd = lws_open(filename, O_RDONLY); 70 ssize_t n; 71 72 if (fd == -1) 73 return -1; 74 75 n = read(fd, buf, len); 76 close(fd); 77 78 return (int)n; 79} 80 81lws_fop_fd_t 82_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, 83 const char *vpath, lws_fop_flags_t *flags) 84{ 85 struct stat stat_buf; 86 int ret = lws_open(filename, (*flags) & LWS_FOP_FLAGS_MASK, 0664); 87 lws_fop_fd_t fop_fd; 88 89 if (ret < 0) 90 return NULL; 91 92 if (fstat(ret, &stat_buf) < 0) 93 goto bail; 94 95 fop_fd = malloc(sizeof(*fop_fd)); 96 if (!fop_fd) 97 goto bail; 98 99 fop_fd->fops = fops; 100 fop_fd->flags = *flags; 101 fop_fd->fd = ret; 102 fop_fd->filesystem_priv = NULL; /* we don't use it */ 103 fop_fd->len = (lws_filepos_t)stat_buf.st_size; 104 fop_fd->pos = 0; 105 106 return fop_fd; 107 108bail: 109 close(ret); 110 return NULL; 111} 112 113int 114_lws_plat_file_close(lws_fop_fd_t *fop_fd) 115{ 116 int fd = (*fop_fd)->fd; 117 118 free(*fop_fd); 119 *fop_fd = NULL; 120 121 return close(fd); 122} 123 124lws_fileofs_t 125_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset) 126{ 127 lws_fileofs_t r; 128 129 if (offset > 0 && 130 offset > (lws_fileofs_t)fop_fd->len - (lws_fileofs_t)fop_fd->pos) 131 offset = (lws_fileofs_t)(fop_fd->len - fop_fd->pos); 132 133 if ((lws_fileofs_t)fop_fd->pos + offset < 0) 134 offset = (lws_fileofs_t)(-fop_fd->pos); 135 136 r = lseek(fop_fd->fd, (off_t)offset, SEEK_CUR); 137 138 if (r >= 0) 139 fop_fd->pos = (lws_filepos_t)r; 140 else 141 lwsl_err("error seeking from cur %ld, offset %ld\n", 142 (long)fop_fd->pos, (long)offset); 143 144 return r; 145} 146 147int 148_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 149 uint8_t *buf, lws_filepos_t len) 150{ 151 ssize_t n; 152 153 n = read((int)fop_fd->fd, buf, (size_t)len); 154 if (n == -1l) { 155 *amount = 0; 156 return -1; 157 } 158 fop_fd->pos = (lws_filepos_t)(fop_fd->pos + (lws_filepos_t)n); 159 lwsl_debug("%s: read %ld of req %ld, pos %ld, len %ld\n", __func__, 160 (long)n, (long)len, (long)fop_fd->pos, 161 (long)fop_fd->len); 162 *amount = (lws_filepos_t)n; 163 164 return 0; 165} 166 167int 168_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 169 uint8_t *buf, lws_filepos_t len) 170{ 171 ssize_t n; 172 173 n = write((int)fop_fd->fd, buf, (size_t)len); 174 if (n == -1) { 175 *amount = 0; 176 return -1; 177 } 178 179 fop_fd->pos = (lws_filepos_t)(fop_fd->pos + (lws_filepos_t)n); 180 *amount = (lws_filepos_t)n; 181 182 return 0; 183} 184 185