lws-vfs.h (9225B)
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/*! \defgroup fops file operation wrapping 26 * 27 * ##File operation wrapping 28 * 29 * Use these helper functions if you want to access a file from the perspective 30 * of a specific wsi, which is usually the case. If you just want contextless 31 * file access, use the fops callbacks directly with NULL wsi instead of these 32 * helpers. 33 * 34 * If so, then it calls the platform handler or user overrides where present 35 * (as defined in info->fops) 36 * 37 * The advantage from all this is user code can be portable for file operations 38 * without having to deal with differences between platforms. 39 */ 40//@{ 41 42/** struct lws_plat_file_ops - Platform-specific file operations 43 * 44 * These provide platform-agnostic ways to deal with filesystem access in the 45 * library and in the user code. 46 */ 47 48#if defined(LWS_PLAT_FREERTOS) 49/* sdk preprocessor defs? compiler issue? gets confused with member names */ 50#define LWS_FOP_OPEN _open 51#define LWS_FOP_CLOSE _close 52#define LWS_FOP_SEEK_CUR _seek_cur 53#define LWS_FOP_READ _read 54#define LWS_FOP_WRITE _write 55#else 56#define LWS_FOP_OPEN open 57#define LWS_FOP_CLOSE close 58#define LWS_FOP_SEEK_CUR seek_cur 59#define LWS_FOP_READ read 60#define LWS_FOP_WRITE write 61#endif 62 63#define LWS_FOP_FLAGS_MASK ((1 << 23) - 1) 64#define LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP (1 << 24) 65#define LWS_FOP_FLAG_COMPR_IS_GZIP (1 << 25) 66#define LWS_FOP_FLAG_MOD_TIME_VALID (1 << 26) 67#define LWS_FOP_FLAG_VIRTUAL (1 << 27) 68 69struct lws_plat_file_ops; 70 71struct lws_fop_fd { 72 lws_filefd_type fd; 73 /**< real file descriptor related to the file... */ 74 const struct lws_plat_file_ops *fops; 75 /**< fops that apply to this fop_fd */ 76 void *filesystem_priv; 77 /**< ignored by lws; owned by the fops handlers */ 78 lws_filepos_t pos; 79 /**< generic "position in file" */ 80 lws_filepos_t len; 81 /**< generic "length of file" */ 82 lws_fop_flags_t flags; 83 /**< copy of the returned flags */ 84 uint32_t mod_time; 85 /**< optional "modification time of file", only valid if .open() 86 * set the LWS_FOP_FLAG_MOD_TIME_VALID flag */ 87}; 88typedef struct lws_fop_fd *lws_fop_fd_t; 89 90struct lws_fops_index { 91 const char *sig; /* NULL or vfs signature, eg, ".zip/" */ 92 uint8_t len; /* length of above string */ 93}; 94 95struct lws_plat_file_ops { 96 lws_fop_fd_t (*LWS_FOP_OPEN)(const struct lws_plat_file_ops *fops, 97 const char *filename, const char *vpath, 98 lws_fop_flags_t *flags); 99 /**< Open file (always binary access if plat supports it) 100 * vpath may be NULL, or if the fops understands it, the point at which 101 * the filename's virtual part starts. 102 * *flags & LWS_FOP_FLAGS_MASK should be set to O_RDONLY or O_RDWR. 103 * If the file may be gzip-compressed, 104 * LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP is set. If it actually is 105 * gzip-compressed, then the open handler should OR 106 * LWS_FOP_FLAG_COMPR_IS_GZIP on to *flags before returning. 107 */ 108 int (*LWS_FOP_CLOSE)(lws_fop_fd_t *fop_fd); 109 /**< close file AND set the pointer to NULL */ 110 lws_fileofs_t (*LWS_FOP_SEEK_CUR)(lws_fop_fd_t fop_fd, 111 lws_fileofs_t offset_from_cur_pos); 112 /**< seek from current position */ 113 int (*LWS_FOP_READ)(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 114 uint8_t *buf, lws_filepos_t len); 115 /**< Read from file, on exit *amount is set to amount actually read */ 116 int (*LWS_FOP_WRITE)(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 117 uint8_t *buf, lws_filepos_t len); 118 /**< Write to file, on exit *amount is set to amount actually written */ 119 120 struct lws_fops_index fi[3]; 121 /**< vfs path signatures implying use of this fops */ 122 123 const struct lws_plat_file_ops *next; 124 /**< NULL or next fops in list */ 125 126 /* Add new things just above here ---^ 127 * This is part of the ABI, don't needlessly break compatibility */ 128}; 129 130/** 131 * lws_get_fops() - get current file ops 132 * 133 * \param context: context 134 */ 135LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops * LWS_WARN_UNUSED_RESULT 136lws_get_fops(struct lws_context *context); 137LWS_VISIBLE LWS_EXTERN void 138lws_set_fops(struct lws_context *context, const struct lws_plat_file_ops *fops); 139/** 140 * lws_vfs_tell() - get current file position 141 * 142 * \param fop_fd: fop_fd we are asking about 143 */ 144LWS_VISIBLE LWS_EXTERN lws_filepos_t LWS_WARN_UNUSED_RESULT 145lws_vfs_tell(lws_fop_fd_t fop_fd); 146/** 147 * lws_vfs_get_length() - get current file total length in bytes 148 * 149 * \param fop_fd: fop_fd we are asking about 150 */ 151LWS_VISIBLE LWS_EXTERN lws_filepos_t LWS_WARN_UNUSED_RESULT 152lws_vfs_get_length(lws_fop_fd_t fop_fd); 153/** 154 * lws_vfs_get_mod_time() - get time file last modified 155 * 156 * \param fop_fd: fop_fd we are asking about 157 */ 158LWS_VISIBLE LWS_EXTERN uint32_t LWS_WARN_UNUSED_RESULT 159lws_vfs_get_mod_time(lws_fop_fd_t fop_fd); 160/** 161 * lws_vfs_file_seek_set() - seek relative to start of file 162 * 163 * \param fop_fd: fop_fd we are seeking in 164 * \param offset: offset from start of file 165 */ 166LWS_VISIBLE LWS_EXTERN lws_fileofs_t 167lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset); 168/** 169 * lws_vfs_file_seek_end() - seek relative to end of file 170 * 171 * \param fop_fd: fop_fd we are seeking in 172 * \param offset: offset from start of file 173 */ 174LWS_VISIBLE LWS_EXTERN lws_fileofs_t 175lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset); 176 177extern struct lws_plat_file_ops fops_zip; 178 179/** 180 * lws_plat_file_open() - open vfs filepath 181 * 182 * \param fops: file ops struct that applies to this descriptor 183 * \param vfs_path: filename to open 184 * \param flags: pointer to open flags 185 * 186 * The vfs_path is scanned for known fops signatures, and the open directed 187 * to any matching fops open. 188 * 189 * User code should use this api to perform vfs opens. 190 * 191 * returns semi-opaque handle 192 */ 193LWS_VISIBLE LWS_EXTERN lws_fop_fd_t LWS_WARN_UNUSED_RESULT 194lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_path, 195 lws_fop_flags_t *flags); 196 197/** 198 * lws_plat_file_close() - close file 199 * 200 * \param fop_fd: file handle to close 201 */ 202static LWS_INLINE int 203lws_vfs_file_close(lws_fop_fd_t *fop_fd) 204{ 205 if (*fop_fd && (*fop_fd)->fops) 206 return (*fop_fd)->fops->LWS_FOP_CLOSE(fop_fd); 207 208 return 0; 209} 210 211/** 212 * lws_plat_file_seek_cur() - close file 213 * 214 * 215 * \param fop_fd: file handle 216 * \param offset: position to seek to 217 */ 218static LWS_INLINE lws_fileofs_t 219lws_vfs_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset) 220{ 221 return fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, offset); 222} 223/** 224 * lws_plat_file_read() - read from file 225 * 226 * \param fop_fd: file handle 227 * \param amount: how much to read (rewritten by call) 228 * \param buf: buffer to write to 229 * \param len: max length 230 */ 231static LWS_INLINE int LWS_WARN_UNUSED_RESULT 232lws_vfs_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 233 uint8_t *buf, lws_filepos_t len) 234{ 235 return fop_fd->fops->LWS_FOP_READ(fop_fd, amount, buf, len); 236} 237/** 238 * lws_plat_file_write() - write from file 239 * 240 * \param fop_fd: file handle 241 * \param amount: how much to write (rewritten by call) 242 * \param buf: buffer to read from 243 * \param len: max length 244 */ 245static LWS_INLINE int LWS_WARN_UNUSED_RESULT 246lws_vfs_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 247 uint8_t *buf, lws_filepos_t len) 248{ 249 return fop_fd->fops->LWS_FOP_WRITE(fop_fd, amount, buf, len); 250} 251 252/* these are the platform file operations implementations... they can 253 * be called directly and used in fops arrays 254 */ 255 256LWS_VISIBLE LWS_EXTERN lws_fop_fd_t 257_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, 258 const char *vpath, lws_fop_flags_t *flags); 259LWS_VISIBLE LWS_EXTERN int 260_lws_plat_file_close(lws_fop_fd_t *fop_fd); 261LWS_VISIBLE LWS_EXTERN lws_fileofs_t 262_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset); 263LWS_VISIBLE LWS_EXTERN int 264_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 265 uint8_t *buf, lws_filepos_t len); 266LWS_VISIBLE LWS_EXTERN int 267_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, 268 uint8_t *buf, lws_filepos_t len); 269 270LWS_VISIBLE LWS_EXTERN int 271lws_alloc_vfs_file(struct lws_context *context, const char *filename, 272 uint8_t **buf, lws_filepos_t *amount); 273//@}