diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-02-17 23:21:28 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-02-17 23:21:28 +0000 |
commit | e3940eb2080711edac189cca3f642ee89dc215f2 (patch) | |
tree | 1c390958fae49e34dce698b175487e6d4681e540 /nuttx/fs/fs_files.c | |
parent | 2223612deb2cc6322992f8595b6d6f86fcb53ae1 (diff) | |
download | px4-nuttx-e3940eb2080711edac189cca3f642ee89dc215f2.tar.gz px4-nuttx-e3940eb2080711edac189cca3f642ee89dc215f2.tar.bz2 px4-nuttx-e3940eb2080711edac189cca3f642ee89dc215f2.zip |
NuttX RTOS
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/fs/fs_files.c')
-rw-r--r-- | nuttx/fs/fs_files.c | 273 |
1 files changed, 273 insertions, 0 deletions
diff --git a/nuttx/fs/fs_files.c b/nuttx/fs/fs_files.c new file mode 100644 index 000000000..7ffede460 --- /dev/null +++ b/nuttx/fs/fs_files.c @@ -0,0 +1,273 @@ +/************************************************************ + * fs_files.c + * + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name Gregory Nutt nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************/ + +/************************************************************ + * Included Files + ************************************************************/ + +#include <nuttx/config.h> + + +#if CONFIG_NFILE_DESCRIPTORS >0 + +#include <string.h> +#include <semaphore.h> +#include <assert.h> +#include <sched.h> +#include <errno.h> +#include <nuttx/fs.h> +#include <nuttx/kmalloc.h> + +#include "fs_internal.h" + +/************************************************************ + * Definitions + ************************************************************/ + +/************************************************************ + * Public Types + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Variables + ************************************************************/ + +/************************************************************ + * Private Functions + ************************************************************/ + +static void _files_semtake(struct filelist *list) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&list->fl_sem) != 0) + { + /* The only case that an error should occr here is if + * the wait was awakened by a signal. + */ + + ASSERT(*get_errno_ptr() == EINTR); + } +} + +static inline void _files_semgive(struct filelist *list) +{ + sem_post(&list->fl_sem); +} + +/************************************************************ + * Pulblic Functions + ************************************************************/ + +/* This is called from the FS initialization logic to configure + * the files. + */ + +void files_initialize(void) +{ +} + +/* Allocate a list of files for a new task */ + +struct filelist *files_alloclist(void) +{ + struct filelist *list; + list = (struct filelist*)kzmalloc(sizeof(struct filelist)); + if (list) + { + /* Start with a reference count of one */ + + list->fl_crefs = 1; + + /* Initialize the list access mutex */ + + (void)sem_init(&list->fl_sem, 0, 1); + } + return list; +} + +/* Increase the reference count on a file list */ + +int files_addreflist(struct filelist *list) +{ + if (list) + { + /* Increment the reference count on the list */ + + _files_semtake(list); + list->fl_crefs++; + _files_semgive(list); + } + return OK; +} + +/* Release a reference to the file list */ + +int files_releaselist(struct filelist *list) +{ + int crefs; + if (list) + { + /* Decrement the reference count */ + + _files_semtake(list); + crefs = --list->fl_crefs; + _files_semgive(list); + + /* If the count decrements to zero, then there is no reference + * to the structure and it should be deallocated. + */ + + if (crefs <= 0) + { + int i; + + /* close each file descriptor */ + + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = list->fl_files[i].f_inode; + if (inode) + { + inode_release(inode); + } + } + + /* Destroy the semaphore and release the filelist */ + + (void)sem_destroy(&list->fl_sem); + sched_free(list); + } + } + return OK; +} + +/* Assign an inode to a specific files structure. this is the + * heart of dup2. + */ + +int files_dup(struct file *filep1, struct file *filep2) +{ + struct filelist *list; + + if (!filep1 || !filep1->f_inode || !filep2) + { + *get_errno_ptr() = EBADF; + return ERROR; + } + + list = sched_getfiles(); + if (!list) + { + *get_errno_ptr() = EMFILE; + return ERROR; + } + + _files_semtake(list); + + /* If there is already an inode contained in the new file structure, + * release it (effectively closing the file). + */ + + if (filep2->f_inode) + { + inode_release(filep2->f_inode); + } + + /* Increment the reference count on the contained inode */ + + inode_addref(filep1->f_inode); + + /* Then clone the file structure */ + + filep2->f_oflags = filep1->f_oflags; + filep2->f_pos = filep1->f_pos; + filep2->f_inode = filep1->f_inode; + _files_semgive(list); + return OK; +} + +/* Allocate a struct files instance and associate it with an + * inode instance. Returns the file descriptor == index into + * the files array. + */ + +int files_allocate(struct inode *inode, int oflags, off_t pos) +{ + struct filelist *list; + int i; + + list = sched_getfiles(); + if (list) + { + _files_semtake(list); + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + if (!list->fl_files[i].f_inode) + { + list->fl_files[i].f_oflags = oflags; + list->fl_files[i].f_pos = pos; + list->fl_files[i].f_inode = inode; + _files_semgive(list); + return i; + } + } + _files_semgive(list); + } + return ERROR; +} + +void files_release(int filedes) +{ + struct filelist *list; + + list = sched_getfiles(); + if (list) + { + if (filedes >=0 && filedes < CONFIG_NFILE_DESCRIPTORS) + { + _files_semtake(list); + list->fl_files[filedes].f_oflags = 0; + list->fl_files[filedes].f_pos = 0; + list->fl_files[filedes].f_inode = NULL; + _files_semgive(list); + } + } +} +#endif /* CONFIG_NFILE_DESCRIPTORS */ |