1 /**************************************************************************** 2 * include/fs/file.h 3 * 4 * Copyright (C) 2007-2009, 2011-2013, 2015-2018 Gregory Nutt. All rights 5 * reserved. 6 * Author: Gregory Nutt <gnutt@nuttx.org> 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 3. Neither the name NuttX nor the names of its contributors may be 19 * used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 ****************************************************************************/ 36 37 #ifndef __INCLUDE_FS_FILE_H 38 #define __INCLUDE_FS_FILE_H 39 40 /**************************************************************************** 41 * Included Files 42 ****************************************************************************/ 43 44 #include "vfs_config.h" 45 46 #include "sys/types.h" 47 #include "sys/stat.h" 48 #include "semaphore.h" 49 #include "poll.h" 50 #include "los_vm_map.h" 51 #include "los_atomic.h" 52 53 #ifdef __cplusplus 54 #if __cplusplus 55 extern "C" { 56 #endif /* __cplusplus */ 57 #endif /* __cplusplus */ 58 59 #ifndef VFS_ERROR 60 #define VFS_ERROR -1 61 #endif 62 63 #ifndef OK 64 #define OK 0 65 #endif 66 67 /* minimal fd allocated for file */ 68 #define FILE_START_FD 3 69 70 struct Vnode; 71 72 /* file mapped in VMM pages */ 73 struct page_mapping { 74 LOS_DL_LIST page_list; /* all pages */ 75 SPIN_LOCK_S list_lock; /* lock protecting it */ 76 LosMux mux_lock; /* mutex lock */ 77 unsigned long nrpages; /* number of total pages */ 78 unsigned long flags; 79 Atomic ref; /* reference counting */ 80 struct Vnode *host; /* owner of this mapping */ 81 }; 82 83 /* This is the underlying representation of an open file. A file 84 * descriptor is an index into an array of such types. The type associates 85 * the file descriptor to the file state and to a set of vnode operations. 86 */ 87 88 struct file 89 { 90 unsigned int f_magicnum; /* file magic number. -- to be deleted */ 91 int f_oflags; /* Open mode flags */ 92 struct Vnode *f_vnode; /* Driver interface */ 93 loff_t f_pos; /* File position */ 94 unsigned long f_refcount; /* reference count */ 95 char *f_path; /* File fullpath */ 96 void *f_priv; /* Per file driver private data */ 97 const char *f_relpath; /* realpath. -- to be deleted */ 98 struct page_mapping *f_mapping; /* mapping file to memory */ 99 void *f_dir; /* DIR struct for iterate the directory if open a directory */ 100 const struct file_operations_vfs *ops; 101 int fd; 102 }; 103 104 /* This defines a list of files indexed by the file descriptor */ 105 106 #if CONFIG_NFILE_DESCRIPTORS > 0 107 struct filelist 108 { 109 sem_t fl_sem; /* Manage access to the file list */ 110 struct file fl_files[CONFIG_NFILE_DESCRIPTORS]; 111 }; 112 113 extern struct filelist tg_filelist; 114 #endif 115 116 /* This structure is provided by devices when they are registered with the 117 * system. It is used to call back to perform device specific operations. 118 */ 119 120 struct file_operations_vfs 121 { 122 /* The device driver open method differs from the mountpoint open method */ 123 124 int (*open)(struct file *filep); 125 126 /* The following methods must be identical in signature and position because 127 * the struct file_operations and struct mountp_operations are treated like 128 * unions. 129 */ 130 131 int (*close)(struct file *filep); 132 ssize_t (*read)(struct file *filep, char *buffer, size_t buflen); 133 ssize_t (*write)(struct file *filep, const char *buffer, size_t buflen); 134 off_t (*seek)(struct file *filep, off_t offset, int whence); 135 int (*ioctl)(struct file *filep, int cmd, unsigned long arg); 136 int (*mmap)(struct file* filep, struct VmMapRegion *region); 137 /* The two structures need not be common after this point */ 138 139 int (*poll)(struct file *filep, poll_table *fds); 140 int (*stat)(struct file *filep, struct stat* st); 141 int (*fallocate)(struct file* filep, int mode, off_t offset, off_t len); 142 int (*fallocate64)(struct file *filep, int mode, off64_t offset, off64_t len); 143 int (*fsync)(struct file *filep); 144 ssize_t (*readpage)(struct file *filep, char *buffer, size_t buflen); 145 int (*unlink)(struct Vnode *vnode); 146 }; 147 148 void file_hold(struct file *filep); 149 void file_release(struct file *filep); 150 151 /**************************************************************************** 152 * Name: files_initlist 153 * 154 * Description: 155 * Initializes the list of files for a new task 156 * 157 ****************************************************************************/ 158 159 #if CONFIG_NFILE_DESCRIPTORS > 0 160 void files_initlist(struct filelist *list); 161 #endif 162 163 /**************************************************************************** 164 * Name: files_releaselist 165 * 166 * Description: 167 * Release a reference to the file list 168 * 169 ****************************************************************************/ 170 171 #if CONFIG_NFILE_DESCRIPTORS > 0 172 void files_releaselist(struct filelist *list); 173 #endif 174 175 /**************************************************************************** 176 * Name: file_dup2 177 * 178 * Description: 179 * Assign an vnode to a specific files structure. This is the heart of 180 * dup2. 181 * 182 * Equivalent to the non-standard fs_dupfd2() function except that it 183 * accepts struct file instances instead of file descriptors and it does 184 * not set the errno variable. 185 * 186 * Returned Value: 187 * Zero (OK) is returned on success; a negated errno value is return on 188 * any failure. 189 * 190 ****************************************************************************/ 191 192 #if CONFIG_NFILE_DESCRIPTORS > 0 193 int file_dup2(struct file *filep1, struct file *filep2); 194 #endif 195 196 /**************************************************************************** 197 * Name: fs_dupfd OR dup 198 * 199 * Description: 200 * Clone a file descriptor 'fd' to an arbitrary descriptor number (any value 201 * greater than or equal to 'minfd'). If socket descriptors are 202 * implemented, then this is called by dup() for the case of file 203 * descriptors. If socket descriptors are not implemented, then this 204 * function IS dup(). 205 * 206 * This alternative naming is used when dup could operate on both file and 207 * socket descriptors to avoid drawing unused socket support into the link. 208 * 209 * Returned Value: 210 * fs_dupfd is sometimes an OS internal function and sometimes is a direct 211 * substitute for dup(). So it must return an errno value as though it 212 * were dup(). 213 * 214 ****************************************************************************/ 215 216 #if CONFIG_NFILE_DESCRIPTORS > 0 217 int fs_dupfd(int fd, int minfd); 218 #endif 219 220 /**************************************************************************** 221 * Name: file_dup 222 * 223 * Description: 224 * Equivalent to the non-standard fs_dupfd() function except that it 225 * accepts a struct file instance instead of a file descriptor and does 226 * not set the errno variable. 227 * 228 * Returned Value: 229 * Zero (OK) is returned on success; a negated errno value is returned on 230 * any failure. 231 * 232 ****************************************************************************/ 233 234 int file_dup(struct file *filep, int minfd); 235 236 /**************************************************************************** 237 * Name: fs_dupfd2 OR dup2 238 * 239 * Description: 240 * Clone a file descriptor to a specific descriptor number. If socket 241 * descriptors are implemented, then this is called by dup2() for the 242 * case of file descriptors. If socket descriptors are not implemented, 243 * then this function IS dup2(). 244 * 245 * This alternative naming is used when dup2 could operate on both file and 246 * socket descriptors to avoid drawing unused socket support into the link. 247 * 248 * Returned Value: 249 * fs_dupfd2 is sometimes an OS internal function and sometimes is a direct 250 * substitute for dup2(). So it must return an errno value as though it 251 * were dup2(). 252 * 253 ****************************************************************************/ 254 255 #if CONFIG_NFILE_DESCRIPTORS > 0 256 int fs_dupfd2(int fd1, int fd2); 257 #endif 258 259 /**************************************************************************** 260 * Name: fs_ioctl 261 * 262 * Description: 263 * Perform device specific operations. 264 * 265 * Input Parameters: 266 * fd File/socket descriptor of device 267 * req The ioctl command 268 * arg The argument of the ioctl cmd 269 * 270 * Returned Value: 271 * >=0 on success (positive non-zero values are cmd-specific) 272 * -1 on failure with errno set properly: 273 * 274 * EBADF 275 * 'fd' is not a valid descriptor. 276 * EFAULT 277 * 'arg' references an inaccessible memory area. 278 * EINVAL 279 * 'cmd' or 'arg' is not valid. 280 * ENOTTY 281 * 'fd' is not associated with a character special device. 282 * ENOTTY 283 * The specified request does not apply to the kind of object that the 284 * descriptor 'fd' references. 285 * 286 ****************************************************************************/ 287 #ifdef CONFIG_LIBC_IOCTL_VARIADIC 288 int fs_ioctl(int fd, int req, unsigned long arg); 289 #endif 290 291 /**************************************************************************** 292 * Name: lib_sendfile 293 * 294 * Description: 295 * Transfer a file 296 * 297 ****************************************************************************/ 298 299 #ifdef CONFIG_NET_SENDFILE 300 ssize_t lib_sendfile(int outfd, int infd, off_t *offset, size_t count); 301 #endif 302 303 /**************************************************************************** 304 * Name: fs_getfilep 305 * 306 * Description: 307 * Given a file descriptor, return the corresponding instance of struct 308 * file. NOTE that this function will currently fail if it is provided 309 * with a socket descriptor. 310 * 311 * Input Parameters: 312 * fd - The file descriptor 313 * filep - The location to return the struct file instance 314 * 315 * Returned Value: 316 * Zero (OK) is returned on success; a negated errno value is returned on 317 * any failure. 318 * 319 ****************************************************************************/ 320 321 #if CONFIG_NFILE_DESCRIPTORS > 0 322 int fs_getfilep(int fd, struct file **filep); 323 #endif 324 325 /**************************************************************************** 326 * Name: file_read 327 * 328 * Description: 329 * file_read() is an internal OS interface. It is functionally similar to 330 * the standard read() interface except: 331 * 332 * - It does not modify the errno variable, 333 * - It is not a cancellation point, 334 * - It does not handle socket descriptors, and 335 * - It accepts a file structure instance instead of file descriptor. 336 * 337 * Input Parameters: 338 * filep - File structure instance 339 * buf - User-provided to save the data 340 * nbytes - The maximum size of the user-provided buffer 341 * 342 * Returned Value: 343 * The positive non-zero number of bytes read on success, 0 on if an 344 * end-of-file condition, or a negated errno value on any failure. 345 * 346 ****************************************************************************/ 347 348 #if CONFIG_NFILE_DESCRIPTORS > 0 349 ssize_t file_read(struct file *filep, void *buf, size_t nbytes); 350 #endif 351 352 /**************************************************************************** 353 * Name: file_write 354 * 355 * Description: 356 * Equivalent to the standard write() function except that is accepts a 357 * struct file instance instead of a file descriptor. Currently used 358 * only by aio_write(); 359 * 360 ****************************************************************************/ 361 362 #if CONFIG_NFILE_DESCRIPTORS > 0 363 ssize_t file_write(struct file *filep, const void *buf, size_t nbytes); 364 #endif 365 366 /**************************************************************************** 367 * Name: file_pread 368 * 369 * Description: 370 * Equivalent to the standard pread function except that is accepts a 371 * struct file instance instead of a file descriptor. Currently used 372 * only by aio_read(); 373 * 374 ****************************************************************************/ 375 376 #if CONFIG_NFILE_DESCRIPTORS > 0 377 ssize_t file_pread(struct file *filep, void *buf, size_t nbytes, 378 off_t offset); 379 #endif 380 381 /**************************************************************************** 382 * Name: file_pwrite 383 * 384 * Description: 385 * Equivalent to the standard pwrite function except that is accepts a 386 * struct file instance instead of a file descriptor. Currently used 387 * only by aio_write(); 388 * 389 ****************************************************************************/ 390 391 #if CONFIG_NFILE_DESCRIPTORS > 0 392 ssize_t file_pwrite(struct file *filep, const void *buf, 393 size_t nbytes, off_t offset); 394 #endif 395 396 /**************************************************************************** 397 * Name: file_seek 398 * 399 * Description: 400 * Equivalent to the standard lseek() function except that is accepts a 401 * struct file instance instead of a file descriptor. Currently used 402 * only by net_sendfile() 403 * 404 ****************************************************************************/ 405 406 #if CONFIG_NFILE_DESCRIPTORS > 0 407 off_t file_seek(struct file *filep, off_t offset, int whence); 408 #endif 409 410 /**************************************************************************** 411 * Name: file_fsync 412 * 413 * Description: 414 * Equivalent to the standard fsync() function except that is accepts a 415 * struct file instance instead of a file descriptor and it does not set 416 * the errno variable. 417 * 418 ****************************************************************************/ 419 420 #if CONFIG_NFILE_DESCRIPTORS > 0 421 int file_fsync(struct file *filep); 422 #endif 423 424 /**************************************************************************** 425 * Name: file_vfcntl 426 * 427 * Description: 428 * Similar to the standard vfcntl function except that is accepts a struct 429 * struct file instance instead of a file descriptor. 430 * 431 * Input Parameters: 432 * filep - Instance for struct file for the opened file. 433 * cmd - Indentifies the operation to be performed. 434 * ap - Variable argument following the command. 435 * 436 * Returned Value: 437 * The nature of the return value depends on the command. Non-negative 438 * values indicate success. Failures are reported as negated errno 439 * values. 440 * 441 ****************************************************************************/ 442 443 #if CONFIG_NFILE_DESCRIPTORS > 0 444 int file_vfcntl(struct file *filep, int cmd, va_list ap); 445 #endif 446 447 /**************************************************************************** 448 * Name: file_seek64 449 * 450 * Description: 451 * Equivalent to the standard lseek64() function except that is accepts a 452 * struct file instance instead of a file descriptor. Currently used 453 * only by net_sendfile() 454 * 455 ****************************************************************************/ 456 457 #if CONFIG_NFILE_DESCRIPTORS > 0 458 off64_t file_seek64(struct file *filep, off64_t offset, int whence); 459 #endif 460 461 /**************************************************************************** 462 * Name: files_allocate 463 * 464 * Description: 465 * Allocate a struct files instance and associate it with an vnode instance. 466 * Returns the file descriptor pointer. 467 * 468 ****************************************************************************/ 469 470 struct file *files_allocate(const struct Vnode *vnode_ptr, int oflags, off_t pos, const void *priv, int minfd); 471 472 /**************************************************************************** 473 * Name: files_close 474 * 475 * Description: 476 * Close an vnode (if open) 477 * 478 * Assumuptions: 479 * Caller holds the list semaphore because the file descriptor will be freed. 480 * 481 ****************************************************************************/ 482 483 int files_close(int fd); 484 485 /**************************************************************************** 486 * Name: files_release 487 * 488 * Assumuptions: 489 * Similar to files_close(). Called only from open() logic on error 490 * conditions. 491 * 492 ****************************************************************************/ 493 494 void files_release(int fd); 495 496 /**************************************************************************** 497 * Name: files_initialize 498 * 499 * Description: 500 * This is called from the FS initialization logic to configure the files. 501 * 502 ****************************************************************************/ 503 504 void WEAK files_initialize(void); 505 506 int vfs_normalize_path(const char *directory, const char *filename, char **pathname); 507 int vfs_normalize_pathat(int fd, const char *filename, char **pathname); 508 509 struct filelist *sched_getfiles(void); 510 511 /* fs/fs_sendfile.c *************************************************/ 512 /**************************************************************************** 513 * Name: sendfile 514 * 515 * Description: 516 * Copy data between one file descriptor and another. 517 * 518 ****************************************************************************/ 519 ssize_t sendfile(int outfd, int infd, off_t *offset, size_t count); 520 521 /** 522 * @ingroup fs 523 * @brief get the path by a given file fd. 524 * 525 * @par Description: 526 * The function is used for getting the path by a given file fd. 527 * 528 * @attention 529 * <ul> 530 * <li>Only support file fd, not any dir fd.</li> 531 * </ul> 532 * 533 * @param fd [IN] Type #int file fd. 534 * @param path [IN] Type #char ** address of the location to return the path reference. 535 * 536 * @retval #0 get path success 537 * @retval #~0 get path failed 538 * 539 * @par Dependency: 540 * <ul><li>fs.h: the header file that contains the API declaration.</li></ul> 541 * @see 542 * 543 * @since 2020-1-8 544 */ 545 546 int get_path_from_fd(int fd, char **path); 547 548 bool get_bit(int i); 549 550 int AllocProcessFd(void); 551 552 int AllocLowestProcessFd(int minFd); 553 554 int AllocSpecifiedProcessFd(int procFd); 555 556 int AllocAndAssocProcessFd(int sysFd, int minFd); 557 558 int AllocAndAssocSystemFd(int procFd, int minFd); 559 560 void AssociateSystemFd(int procFd, int sysFd); 561 562 int DisassociateProcessFd(int procFd); 563 564 int GetAssociatedSystemFd(int procFd); 565 566 int CheckProcessFd(int procFd); 567 568 void FreeProcessFd(int procFd); 569 570 int CopyFdToProc(int fd, unsigned int targetPid); 571 572 int CloseProcFd(int fd, unsigned int targetPid); 573 574 void lsfd(void); 575 576 void set_sd_sync_fn(int (*sync_fn)(int)); 577 578 struct Vnode *files_get_openfile(int fd); 579 580 void poll_wait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p); 581 582 int follow_symlink(int dirfd, const char *path, struct Vnode **vnode, char **fullpath); 583 #ifdef __cplusplus 584 #if __cplusplus 585 } 586 #endif /* __cplusplus */ 587 #endif /* __cplusplus */ 588 #endif /* __INCLUDE_FS_FILE_H */ 589