Finish dup logic for open files; fix bug in sigtimedwait(), would return wrong signo value if the signal was already pending
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5517 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
555e3fe1f5
commit
5a2eda210b
@ -3940,3 +3940,12 @@
|
||||
implemented).
|
||||
* fs/romfs: Remove the rf_open flag. It looks good, but actually
|
||||
does nothing.
|
||||
* fs/fat: Remove the ff_open flag. Same story as for the ROMFS
|
||||
rf_open flag.
|
||||
* fs/fat/fs_fat32.c, fs/nxffs/nxffs_initialize, and
|
||||
fs/nfs/nfs_vfsops.c: Completed implementation of the dup() methods.
|
||||
There is still no good test available.
|
||||
* sched/sig_timedwait.c: sigtimedwait() would return a bad signal
|
||||
number if the signal was already pending when the function was
|
||||
called.
|
||||
called.
|
||||
|
24
TODO
24
TODO
@ -1,4 +1,4 @@
|
||||
NuttX TODO List (Last updated January 13, 2013)
|
||||
NuttX TODO List (Last updated January 14, 2013)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This file summarizes known NuttX bugs, limitations, inconsistencies with
|
||||
@ -15,7 +15,7 @@ nuttx/
|
||||
(17) Network (net/, drivers/net)
|
||||
(4) USB (drivers/usbdev, drivers/usbhost)
|
||||
(12) Libraries (libc/, )
|
||||
(10) File system/Generic drivers (fs/, drivers/)
|
||||
(9) File system/Generic drivers (fs/, drivers/)
|
||||
(5) Graphics subystem (graphics/)
|
||||
(1) Pascal add-on (pcode/)
|
||||
(1) Documentation (Documentation/)
|
||||
@ -879,26 +879,6 @@ o File system / Generic drivers (fs/, drivers/)
|
||||
Status: Open
|
||||
Priority: Medium
|
||||
|
||||
Title: dup AND dup2 WILL NOT WORK ON FILES IN A MOUNTED VOLUME
|
||||
Description: The current implementation of dup() and dup2() will only
|
||||
work with open device drivers and sockets. It will not
|
||||
work with open files in a file system. Support for dup'ing
|
||||
open files on a mounted volume has not been implemented yet.
|
||||
|
||||
There is a stubbed out, partial implemenation in fs/fs_files.c.
|
||||
In would perform the dup2() operation by re-opening the file
|
||||
and setting the file pointer. The logic, however, would require
|
||||
that we remember the (relative) path to the file in the mounted
|
||||
volume for each open file.
|
||||
|
||||
An option might to add a dup() method to the file system
|
||||
mountpoint interface.
|
||||
|
||||
A limitation that results from this is that you cannot
|
||||
redirect I/O to an from and file.
|
||||
Status: Open
|
||||
Priority: High
|
||||
|
||||
o Graphics subystem (graphics/)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/fat/fs_fat32.c
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References:
|
||||
@ -86,7 +86,9 @@ static ssize_t fat_write(FAR struct file *filep, const char *buffer,
|
||||
size_t buflen);
|
||||
static off_t fat_seek(FAR struct file *filep, off_t offset, int whence);
|
||||
static int fat_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
|
||||
static int fat_sync(FAR struct file *filep);
|
||||
static int fat_dup(FAR const struct file *oldp, FAR struct file *newp);
|
||||
|
||||
static int fat_opendir(struct inode *mountpt, const char *relpath,
|
||||
struct fs_dirent_s *dir);
|
||||
@ -129,7 +131,7 @@ const struct mountpt_operations fat_operations =
|
||||
fat_ioctl, /* ioctl */
|
||||
|
||||
fat_sync, /* sync */
|
||||
NULL, /* dup */
|
||||
fat_dup, /* dup */
|
||||
|
||||
fat_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
@ -313,7 +315,6 @@ static int fat_open(FAR struct file *filep, const char *relpath,
|
||||
|
||||
/* Initialize the file private data (only need to initialize non-zero elements) */
|
||||
|
||||
ff->ff_open = true;
|
||||
ff->ff_oflags = oflags;
|
||||
|
||||
/* Save information that can be used later to recover the directory entry */
|
||||
@ -898,6 +899,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
|
||||
DEBUGASSERT(fs != NULL);
|
||||
|
||||
/* Map the offset according to the whence option */
|
||||
|
||||
switch (whence)
|
||||
{
|
||||
case SEEK_SET: /* The offset is set to offset bytes. */
|
||||
@ -971,6 +973,7 @@ static off_t fat_seek(FAR struct file *filep, off_t offset, int whence)
|
||||
ret = cluster;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
ff->ff_startcluster = cluster;
|
||||
}
|
||||
|
||||
@ -1232,6 +1235,123 @@ errout_with_semaphore:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_dup
|
||||
*
|
||||
* Description: Duplicate open file data in the new file structure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int fat_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
{
|
||||
FAR struct fat_mountpt_s *fs;
|
||||
FAR struct fat_file_s *oldff;
|
||||
FAR struct fat_file_s *newff;
|
||||
int ret;
|
||||
|
||||
fvdbg("Dup %p->%p\n", oldp, newp);
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(oldp->f_priv != NULL &&
|
||||
newp->f_priv == NULL &&
|
||||
newp->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
fs = (struct fat_mountpt_s *)oldp->f_inode->i_private;
|
||||
DEBUGASSERT(fs != NULL);
|
||||
|
||||
/* Check if the mount is still healthy */
|
||||
|
||||
fat_semtake(fs);
|
||||
ret = fat_checkmount(fs);
|
||||
if (ret != OK)
|
||||
{
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Recover the old private data from the old struct file instance */
|
||||
|
||||
oldff = oldp->f_priv;
|
||||
|
||||
/* Create a new instance of the file private date to describe the
|
||||
* dup'ed file.
|
||||
*/
|
||||
|
||||
newff = (struct fat_file_s *)kmalloc(sizeof(struct fat_file_s));
|
||||
if (!newff)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* Create a file buffer to support partial sector accesses */
|
||||
|
||||
newff->ff_buffer = (uint8_t*)fat_io_alloc(fs->fs_hwsectorsize);
|
||||
if (!newff->ff_buffer)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
goto errout_with_struct;
|
||||
}
|
||||
|
||||
/* Copy the rest of the open open file state from the old file structure.
|
||||
* There are some assumptions and potential issues here:
|
||||
*
|
||||
* 1) We assume that the higher level logic has copied the elements of
|
||||
* the file structure, in particular, the file position.
|
||||
* 2) There is a problem with ff_size if there are multiple opened
|
||||
* file structures, each believing they know the size of the file.
|
||||
* If one instance modifies the file length, then the new size of
|
||||
* the opened file will be unknown to the other. That is a lurking
|
||||
* bug!
|
||||
*
|
||||
* One good solution to this might be to add a refernce count to the
|
||||
* file structure. Then, instead of dup'ing the whole structure
|
||||
* as is done here, just increment the reference count on the
|
||||
* structure. The would have to be integrated with open logic as
|
||||
* well, however, so that the same file structure is re-used if the
|
||||
* file is re-opened.
|
||||
*/
|
||||
|
||||
newff->ff_bflags = 0;
|
||||
newff->ff_oflags = oldff->ff_oflags;
|
||||
newff->ff_sectorsincluster = oldff->ff_sectorsincluster;
|
||||
newff->ff_dirindex = oldff->ff_dirindex;
|
||||
newff->ff_currentcluster = oldff->ff_currentcluster;
|
||||
newff->ff_dirsector = oldff->ff_dirsector;
|
||||
newff->ff_size = oldff->ff_size;
|
||||
newff->ff_currentsector = 0;
|
||||
newff->ff_cachesector = 0;
|
||||
|
||||
/* Attach the private date to the struct file instance */
|
||||
|
||||
newp->f_priv = newff;
|
||||
|
||||
/* Then insert the new instance into the mountpoint structure.
|
||||
* It needs to be there (1) to handle error conditions that effect
|
||||
* all files, and (2) to inform the umount logic that we are busy
|
||||
* (but a simple reference count could have done that).
|
||||
*/
|
||||
|
||||
newff->ff_next = fs->fs_head;
|
||||
fs->fs_head = newff->ff_next;
|
||||
|
||||
fat_semgive(fs);
|
||||
return OK;
|
||||
|
||||
/* Error exits -- goto's are nasty things, but they sure can make error
|
||||
* handling a lot simpler.
|
||||
*/
|
||||
|
||||
errout_with_struct:
|
||||
kfree(newff);
|
||||
|
||||
errout_with_semaphore:
|
||||
fat_semgive(fs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: fat_opendir
|
||||
*
|
||||
|
@ -752,7 +752,6 @@ struct fat_mountpt_s
|
||||
struct fat_file_s
|
||||
{
|
||||
struct fat_file_s *ff_next; /* Retained in a singly linked list */
|
||||
bool ff_open; /* true: The file is (still) open */
|
||||
uint8_t ff_bflags; /* The file buffer flags */
|
||||
uint8_t ff_oflags; /* Flags provided when file was opened */
|
||||
uint8_t ff_sectorsincluster; /* Sectors remaining in cluster */
|
||||
|
@ -692,8 +692,6 @@ int fat_checkmount(struct fat_mountpt_s *fs)
|
||||
|
||||
if (fs && fs->fs_mounted)
|
||||
{
|
||||
struct fat_file_s *file;
|
||||
|
||||
/* We still think the mount is healthy. Check an see if this is
|
||||
* still the case
|
||||
*/
|
||||
@ -715,14 +713,8 @@ int fat_checkmount(struct fat_mountpt_s *fs)
|
||||
/* If we get here, the mount is NOT healthy */
|
||||
|
||||
fs->fs_mounted = false;
|
||||
|
||||
/* Make sure that this is flagged in every opened file */
|
||||
|
||||
for (file = fs->fs_head; file; file = file->ff_next)
|
||||
{
|
||||
file->ff_open = false;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/nfs/nfs_node.h
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
|
||||
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -70,6 +70,7 @@
|
||||
struct nfsnode
|
||||
{
|
||||
struct nfsnode *n_next; /* Retained in a singly linked list. */
|
||||
uint8_t n_crefs; /* Reference count (for nfs_dup) */
|
||||
uint8_t n_type; /* File type */
|
||||
uint8_t n_fhsize; /* Size in bytes of the file handle */
|
||||
uint8_t n_flags; /* Node flags */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/nfs/nfs_util.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -213,7 +213,6 @@ int nfs_request(struct nfsmount *nmp, int procnum,
|
||||
{
|
||||
struct rpcclnt *clnt = nmp->nm_rpcclnt;
|
||||
struct nfs_reply_header replyh;
|
||||
int trylater_delay;
|
||||
int error;
|
||||
|
||||
tryagain:
|
||||
@ -250,12 +249,6 @@ tryagain:
|
||||
if (error == EAGAIN)
|
||||
{
|
||||
error = 0;
|
||||
trylater_delay *= NFS_TIMEOUTMUL;
|
||||
if (trylater_delay > NFS_MAXTIMEO)
|
||||
{
|
||||
trylater_delay = NFS_MAXTIMEO;
|
||||
}
|
||||
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/nfs/nfs_vfsops.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
|
||||
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -133,6 +133,7 @@ static int nfs_close(FAR struct file *filep);
|
||||
static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen);
|
||||
static ssize_t nfs_write(FAR struct file *filep, const char *buffer,
|
||||
size_t buflen);
|
||||
static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp);
|
||||
static int nfs_opendir(struct inode *mountpt, const char *relpath,
|
||||
struct fs_dirent_s *dir);
|
||||
static int nfs_readdir(struct inode *mountpt, struct fs_dirent_s *dir);
|
||||
@ -168,7 +169,7 @@ const struct mountpt_operations nfs_operations =
|
||||
NULL, /* ioctl */
|
||||
|
||||
NULL, /* sync */
|
||||
NULL, /* dup */
|
||||
nfs_dup, /* dup */
|
||||
|
||||
nfs_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
@ -359,7 +360,7 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
|
||||
|
||||
/* Save the attributes in the file data structure */
|
||||
|
||||
tmp = *ptr++; /* handle_follows */
|
||||
tmp = *ptr; /* handle_follows */
|
||||
if (!tmp)
|
||||
{
|
||||
fdbg("WARNING: no file attributes\n");
|
||||
@ -369,7 +370,6 @@ static int nfs_filecreate(FAR struct nfsmount *nmp, struct nfsnode *np,
|
||||
/* Initialize the file attributes */
|
||||
|
||||
nfs_attrupdate(np, (FAR struct nfs_fattr *)ptr);
|
||||
ptr += uint32_increment(sizeof(struct nfs_fattr));
|
||||
}
|
||||
|
||||
/* Any following dir_wcc data is ignored for now */
|
||||
@ -412,7 +412,7 @@ static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np)
|
||||
reqlen += (int)np->n_fhsize;
|
||||
ptr += uint32_increment(np->n_fhsize);
|
||||
|
||||
/* Copy the variable-length attribtes */
|
||||
/* Copy the variable-length attributes */
|
||||
|
||||
*ptr++ = nfs_false; /* Don't change mode */
|
||||
*ptr++ = nfs_false; /* Don't change uid */
|
||||
@ -423,7 +423,7 @@ static int nfs_filetruncate(FAR struct nfsmount *nmp, struct nfsnode *np)
|
||||
*ptr++ = HTONL(NFSV3SATTRTIME_TOSERVER); /* Use the server's time */
|
||||
*ptr++ = HTONL(NFSV3SATTRTIME_TOSERVER); /* Use the server's time */
|
||||
*ptr++ = nfs_false; /* No guard value */
|
||||
reqlen += 9*sizeof(uint32_t)
|
||||
reqlen += 9 * sizeof(uint32_t);
|
||||
|
||||
/* Perform the SETATTR RPC */
|
||||
|
||||
@ -553,9 +553,9 @@ static int nfs_fileopen(FAR struct nfsmount *nmp, struct nfsnode *np,
|
||||
static int nfs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
int oflags, mode_t mode)
|
||||
{
|
||||
struct nfsmount *nmp;
|
||||
struct nfsnode *np = NULL;
|
||||
int error;
|
||||
struct nfsmount *nmp;
|
||||
struct nfsnode *np;
|
||||
int error;
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
@ -634,6 +634,8 @@ static int nfs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
* non-zero elements)
|
||||
*/
|
||||
|
||||
np->n_crefs = 1;
|
||||
|
||||
/* Attach the private data to the struct file instance */
|
||||
|
||||
filep->f_priv = np;
|
||||
@ -656,6 +658,7 @@ errout_with_semaphore:
|
||||
{
|
||||
kfree(np);
|
||||
}
|
||||
|
||||
nfs_semgive(nmp);
|
||||
return -error;
|
||||
}
|
||||
@ -693,8 +696,22 @@ static int nfs_close(FAR struct file *filep)
|
||||
|
||||
nfs_semtake(nmp);
|
||||
|
||||
/* Find our file structure in the list of file structures containted in the
|
||||
* mount structure.
|
||||
/* Decrement the reference count. If the reference count would not
|
||||
* decrement to zero, then that is all we have to do.
|
||||
*/
|
||||
|
||||
if (np->n_crefs > 1)
|
||||
{
|
||||
np->n_crefs--;
|
||||
nfs_semgive(nmp);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* There are no more references to the file structure. Now we need to
|
||||
* free up all resources associated with the open file.
|
||||
*
|
||||
* First, find our file structure in the list of file structures
|
||||
* containted in the mount structure.
|
||||
*/
|
||||
|
||||
for (prev = NULL, curr = nmp->nm_head; curr; prev = curr, curr = curr->n_next)
|
||||
@ -759,8 +776,8 @@ static ssize_t nfs_read(FAR struct file *filep, char *buffer, size_t buflen)
|
||||
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
nmp = (struct nfsmount*) filep->f_inode->i_private;
|
||||
np = (struct nfsnode*) filep->f_priv;
|
||||
nmp = (struct nfsmount*)filep->f_inode->i_private;
|
||||
np = (struct nfsnode*)filep->f_priv;
|
||||
|
||||
DEBUGASSERT(nmp != NULL);
|
||||
|
||||
@ -1093,6 +1110,66 @@ errout_with_semaphore:
|
||||
return -error;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: binfs_dup
|
||||
*
|
||||
* Description:
|
||||
* Duplicate open file data in the new file structure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int nfs_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
{
|
||||
struct nfsmount *nmp;
|
||||
FAR struct nfsnode *np;
|
||||
int error;
|
||||
|
||||
fvdbg("Dup %p->%p\n", oldp, newp);
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
DEBUGASSERT(oldp->f_priv != NULL && oldp->f_inode != NULL);
|
||||
|
||||
/* Recover our private data from the struct file instance */
|
||||
|
||||
nmp = (struct nfsmount*)oldp->f_inode->i_private;
|
||||
np = (struct nfsnode*)oldp->f_priv;
|
||||
|
||||
DEBUGASSERT(nmp != NULL);
|
||||
|
||||
/* Check if the mount is still healthy */
|
||||
|
||||
nfs_semtake(nmp);
|
||||
error = nfs_checkmount(nmp);
|
||||
if (error != OK)
|
||||
{
|
||||
fdbg("ERROR: nfs_checkmount failed: %d\n", error);
|
||||
nfs_semgive(nmp);
|
||||
return -error;
|
||||
}
|
||||
|
||||
/* Increment the reference count on the NFS node structure */
|
||||
|
||||
DEBUGASSERT(np->n_crefs < 0xff);
|
||||
np->n_crefs++;
|
||||
|
||||
/* And save this as the file data for the new node */
|
||||
|
||||
newp->f_priv = np;
|
||||
|
||||
/* Then insert the new instance at the head of the list in the mountpoint
|
||||
* tructure. It needs to be there (1) to handle error conditions that effect
|
||||
* all files, and (2) to inform the umount logic that we are busy. We
|
||||
* cannot unmount the file system if this list is not empty!
|
||||
*/
|
||||
|
||||
np->n_next = nmp->nm_head;
|
||||
nmp->nm_head = np;
|
||||
|
||||
nfs_semgive(nmp);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nfs_opendir
|
||||
*
|
||||
@ -1756,12 +1833,15 @@ bad:
|
||||
{
|
||||
kfree(nmp->nm_so);
|
||||
}
|
||||
|
||||
if (nmp->nm_rpcclnt)
|
||||
{
|
||||
kfree(nmp->nm_rpcclnt);
|
||||
}
|
||||
|
||||
kfree(nmp);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/nfs/rpc_clnt.c
|
||||
*
|
||||
* Copyright (C) 2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2012 Jose Pablo Rojas Vargas. All rights reserved.
|
||||
* Author: Jose Pablo Rojas Vargas <jrojas@nx-engineering.com>
|
||||
* Gregory Nutt <gnutt@nuttx.org>
|
||||
@ -224,8 +224,6 @@ static int rpcclnt_receive(FAR struct rpcclnt *rpc, FAR struct sockaddr *aname,
|
||||
static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
|
||||
FAR void *reply, size_t resplen)
|
||||
{
|
||||
FAR struct rpc_reply_header *replyheader;
|
||||
uint32_t rxid;
|
||||
int error;
|
||||
|
||||
/* Get the next RPC reply from the socket */
|
||||
@ -235,22 +233,22 @@ static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
|
||||
{
|
||||
fdbg("ERROR: rpcclnt_receive returned: %d\n", error);
|
||||
|
||||
/* If we failed because of a timeout, then try sending the CALL
|
||||
* message again.
|
||||
*/
|
||||
/* If we failed because of a timeout, then try sending the CALL
|
||||
* message again.
|
||||
*/
|
||||
|
||||
if (error == EAGAIN || error == ETIMEDOUT)
|
||||
{
|
||||
rpc->rc_timeout = true;
|
||||
}
|
||||
}
|
||||
if (error == EAGAIN || error == ETIMEDOUT)
|
||||
{
|
||||
rpc->rc_timeout = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the xid and check that it is an RPC replysvr */
|
||||
|
||||
else
|
||||
{
|
||||
replyheader = (FAR struct rpc_reply_header *)reply;
|
||||
rxid = replyheader->rp_xid;
|
||||
FAR struct rpc_reply_header *replyheader =
|
||||
(FAR struct rpc_reply_header *)reply;
|
||||
|
||||
if (replyheader->rp_direction != rpc_reply)
|
||||
{
|
||||
@ -260,7 +258,7 @@ static int rpcclnt_reply(FAR struct rpcclnt *rpc, int procid, int prog,
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
return error;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -275,7 +273,6 @@ static uint32_t rpcclnt_newxid(void)
|
||||
{
|
||||
static uint32_t rpcclnt_xid = 0;
|
||||
static uint32_t rpcclnt_xid_touched = 0;
|
||||
int xidp = 0;
|
||||
|
||||
srand(time(NULL));
|
||||
if ((rpcclnt_xid == 0) && (rpcclnt_xid_touched == 0))
|
||||
@ -285,6 +282,7 @@ static uint32_t rpcclnt_newxid(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
int xidp = 0;
|
||||
do
|
||||
{
|
||||
xidp = rand();
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/nxffs/nxffs.h
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References: Linux/Documentation/filesystems/romfs.txt
|
||||
@ -1044,6 +1044,7 @@ extern int nxffs_pack(FAR struct nxffs_volume_s *volume);
|
||||
* - nxffs_read() is defined in nxffs_read.c
|
||||
* - nxffs_write() is defined in nxffs_write.c
|
||||
* - nxffs_ioctl() is defined in nxffs_ioctl.c
|
||||
* - nxffs_dup() is defined in nxffs_open.c
|
||||
* - nxffs_opendir(), nxffs_readdir(), and nxffs_rewindir() are defined in
|
||||
* nxffs_dirent.c
|
||||
* - nxffs_bind() and nxffs_unbind() are defined in nxffs_initialize.c
|
||||
@ -1058,25 +1059,25 @@ struct fs_dirent_s;
|
||||
struct statfs;
|
||||
struct stat;
|
||||
|
||||
extern int nxffs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
int oflags, mode_t mode);
|
||||
extern int nxffs_close(FAR struct file *filep);
|
||||
extern ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen);
|
||||
extern ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t buflen);
|
||||
extern int nxffs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
extern int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
extern int nxffs_readdir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
|
||||
extern int nxffs_rewinddir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
|
||||
extern int nxffs_bind(FAR struct inode *blkdriver, FAR const void *data,
|
||||
FAR void **handle);
|
||||
extern int nxffs_unbind(FAR void *handle, FAR struct inode **blkdriver);
|
||||
extern int nxffs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf);
|
||||
extern int nxffs_stat(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct stat *buf);
|
||||
extern int nxffs_unlink(FAR struct inode *mountpt, FAR const char *relpath);
|
||||
int nxffs_open(FAR struct file *filep, FAR const char *relpath, int oflags,
|
||||
mode_t mode);
|
||||
int nxffs_close(FAR struct file *filep);
|
||||
ssize_t nxffs_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
|
||||
ssize_t nxffs_write(FAR struct file *filep, FAR const char *buffer,
|
||||
size_t buflen);
|
||||
int nxffs_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
|
||||
int nxffs_dup(FAR const struct file *oldp, FAR struct file *newp);
|
||||
int nxffs_opendir(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct fs_dirent_s *dir);
|
||||
int nxffs_readdir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
|
||||
int nxffs_rewinddir(FAR struct inode *mountpt, FAR struct fs_dirent_s *dir);
|
||||
int nxffs_bind(FAR struct inode *blkdriver, FAR const void *data,
|
||||
FAR void **handle);
|
||||
int nxffs_unbind(FAR void *handle, FAR struct inode **blkdriver);
|
||||
int nxffs_statfs(FAR struct inode *mountpt, FAR struct statfs *buf);
|
||||
int nxffs_stat(FAR struct inode *mountpt, FAR const char *relpath,
|
||||
FAR struct stat *buf);
|
||||
int nxffs_unlink(FAR struct inode *mountpt, FAR const char *relpath);
|
||||
|
||||
#endif /* __FS_NXFFS_NXFFS_H */
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/nxffs/nxffs_initialize.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References: Linux/Documentation/filesystems/romfs.txt
|
||||
@ -84,7 +84,7 @@ const struct mountpt_operations nxffs_operations =
|
||||
nxffs_ioctl, /* ioctl */
|
||||
|
||||
NULL, /* sync -- No buffered data */
|
||||
NULL, /* dup -- not implemented */
|
||||
nxffs_dup, /* dup */
|
||||
|
||||
nxffs_opendir, /* opendir */
|
||||
NULL, /* closedir */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* fs/nxffs/nxffs_open.c
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2011, 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* References: Linux/Documentation/filesystems/romfs.txt
|
||||
@ -1023,7 +1023,7 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
#endif
|
||||
|
||||
/* Limitation: A file must be opened for reading or writing, but not both.
|
||||
* There is no general for extending the size of of a file. Extending the
|
||||
* There is no general way of extending the size of a file. Extending the
|
||||
* file size of possible if the file to be extended is the last in the
|
||||
* sequence on FLASH, but since that case is not the general case, no file
|
||||
* extension is supported.
|
||||
@ -1058,6 +1058,64 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: binfs_dup
|
||||
*
|
||||
* Description:
|
||||
* Duplicate open file data in the new file structure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nxffs_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG
|
||||
FAR struct nxffs_volume_s *volume;
|
||||
#endif
|
||||
FAR struct nxffs_ofile_s *ofile;
|
||||
|
||||
fvdbg("Dup %p->%p\n", oldp, newp);
|
||||
|
||||
/* Sanity checks */
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
DEBUGASSERT(oldp->f_priv == NULL && oldp->f_inode != NULL);
|
||||
|
||||
/* Get the mountpoint private data from the NuttX inode reference in the
|
||||
* file structure
|
||||
*/
|
||||
|
||||
volume = (FAR struct nxffs_volume_s*)oldp->f_inode->i_private;
|
||||
DEBUGASSERT(volume != NULL);
|
||||
#endif
|
||||
|
||||
/* Recover the open file state from the struct file instance */
|
||||
|
||||
ofile = (FAR struct nxffs_ofile_s *)oldp->f_priv;
|
||||
|
||||
/* I do not think we need exclusive access to the volume to do this.
|
||||
* The volume exclsem protects the open file list and, hence, would
|
||||
* assure that the ofile is stable. However, it is assumed that the
|
||||
* caller holds a value file descriptor associated with this ofile,
|
||||
* so it should be stable throughout the life of this function.
|
||||
*/
|
||||
|
||||
/* Limitations: I do not think we have to be concerned about the
|
||||
* usual NXFFS file limitations here: dup'ing cannot resulting
|
||||
* in mixed reading and writing to the same file, or multiple
|
||||
* writer to different file.
|
||||
*
|
||||
* I notice that nxffs_wropen will prohibit multiple opens for
|
||||
* writing. But I do not thing that dup'ing a file already opened
|
||||
* for writing suffers from any of these issues.
|
||||
*/
|
||||
|
||||
/* Just increment the reference count on the ofile */
|
||||
|
||||
ofile->crefs++;
|
||||
newp->f_priv = (FAR void *)ofile;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxffs_close
|
||||
*
|
||||
|
@ -636,7 +636,7 @@ static int romfs_dup(FAR const struct file *oldp, FAR struct file *newp)
|
||||
* dup'ed file.
|
||||
*/
|
||||
|
||||
newrf = (FAR struct romfs_file_s *)malloc(sizeof(struct romfs_file_s));
|
||||
newrf = (FAR struct romfs_file_s *)kmalloc(sizeof(struct romfs_file_s));
|
||||
if (!newrf)
|
||||
{
|
||||
fdbg("Failed to allocate private data\n", ret);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/fs/fs.h
|
||||
*
|
||||
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009, 2011-2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -217,11 +217,11 @@ void mq_initialize(void)
|
||||
|
||||
void mq_desblockalloc(void)
|
||||
{
|
||||
struct mq_des_block_s *mqdesblock;
|
||||
FAR struct mq_des_block_s *mqdesblock;
|
||||
|
||||
/* Allocate a block of message descriptors */
|
||||
|
||||
mqdesblock = (struct mq_des_block_s *)kmalloc(sizeof(struct mq_des_block_s));
|
||||
mqdesblock = (FAR struct mq_des_block_s *)kmalloc(sizeof(struct mq_des_block_s));
|
||||
if (mqdesblock)
|
||||
{
|
||||
int i;
|
||||
|
@ -228,7 +228,7 @@ int sigtimedwait(FAR const sigset_t *set, FAR struct siginfo *info,
|
||||
|
||||
/* The return value is the number of the signal that awakened us */
|
||||
|
||||
ret = info->si_signo;
|
||||
ret = sigpend->info.si_signo;
|
||||
}
|
||||
|
||||
/* We will have to wait for a signal to be posted to this task. */
|
||||
|
@ -291,7 +291,7 @@ pid_t task_vforkstart(FAR _TCB *child)
|
||||
* still running.
|
||||
*/
|
||||
|
||||
while ((ret = kill(pid, 0)) == OK)
|
||||
while (kill(pid, 0) == OK)
|
||||
{
|
||||
/* Yes.. then we can yield to it -- assuming that it has not lowered
|
||||
* its priority. sleep(0) might be a safer thing to do since it does
|
||||
|
Loading…
Reference in New Issue
Block a user