fs: Support the root file system attributes(mode, uid, gid and time)
Note: all attributes is guarded by PSEUDOFS_ATTRIBUTES to save the space Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com> Change-Id: I664d60382e356068fd920f08aca5b4a49d8d92a9
This commit is contained in:
parent
09f3a1ec8e
commit
0148e1d501
@ -47,6 +47,14 @@ config DISABLE_PSEUDOFS_OPERATIONS
|
||||
However, in practical embedded system, they are seldom needed and
|
||||
you can save a little FLASH space by disabling the capability.
|
||||
|
||||
config PSEUDOFS_ATTRIBUTES
|
||||
bool "Pseudo-filesystem attributes"
|
||||
default n
|
||||
depends on !DISABLE_PSEUDOFS_OPERATIONS
|
||||
---help---
|
||||
Enable support for attributes(e.g. mode, uid, gid and time)
|
||||
in the pseudo file system.
|
||||
|
||||
config PSEUDOFS_SOFTLINKS
|
||||
bool "Pseudo-filesystem soft links"
|
||||
default n
|
||||
|
@ -46,7 +46,7 @@
|
||||
* Input Parameters:
|
||||
* path - The path to the inode to create
|
||||
* bops - The block driver operations structure
|
||||
* mode - inmode privileges (not used)
|
||||
* mode - inmode privileges
|
||||
* priv - Private, user data that will be associated with the inode.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -79,7 +79,7 @@ int register_blockdriver(FAR const char *path,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = inode_reserve(path, &node);
|
||||
ret = inode_reserve(path, mode, &node);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* We have it, now populate it with block driver specific information.
|
||||
@ -89,9 +89,6 @@ int register_blockdriver(FAR const char *path,
|
||||
INODE_SET_BLOCK(node);
|
||||
|
||||
node->u.i_bops = bops;
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
node->i_mode = mode;
|
||||
#endif
|
||||
node->i_private = priv;
|
||||
ret = OK;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
||||
* Input Parameters:
|
||||
* path - The path to the inode to create
|
||||
* fops - The file operations structure
|
||||
* mode - inmode privileges (not used)
|
||||
* mode - inmode privileges
|
||||
* priv - Private, user data that will be associated with the inode.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -75,7 +75,7 @@ int register_driver(FAR const char *path,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = inode_reserve(path, &node);
|
||||
ret = inode_reserve(path, mode, &node);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* We have it, now populate it with driver specific information.
|
||||
@ -85,9 +85,6 @@ int register_driver(FAR const char *path,
|
||||
INODE_SET_DRIVER(node);
|
||||
|
||||
node->u.i_ops = fops;
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
node->i_mode = mode;
|
||||
#endif
|
||||
node->i_private = priv;
|
||||
ret = OK;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@
|
||||
* Input Parameters:
|
||||
* path - The path to the inode to create
|
||||
* mtd - The MTD driver structure
|
||||
* mode - inode privileges (not used)
|
||||
* mode - inode privileges
|
||||
* priv - Private, user data that will be associated with the inode.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -79,7 +79,7 @@ int register_mtddriver(FAR const char *path, FAR struct mtd_dev_s *mtd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = inode_reserve(path, &node);
|
||||
ret = inode_reserve(path, mode, &node);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* We have it, now populate it with block driver specific information.
|
||||
@ -89,9 +89,6 @@ int register_mtddriver(FAR const char *path, FAR struct mtd_dev_s *mtd,
|
||||
INODE_SET_MTD(node);
|
||||
|
||||
node->u.i_mtd = mtd;
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
node->i_mode = mode;
|
||||
#endif
|
||||
node->i_private = priv;
|
||||
ret = OK;
|
||||
}
|
||||
|
@ -226,10 +226,6 @@ static int fat_open(FAR struct file *filep, FAR const char *relpath,
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
/* TODO: if CONFIG_FILE_MODE=y, need check for privileges based on
|
||||
* inode->i_mode
|
||||
*/
|
||||
|
||||
/* Check if the caller has sufficient privileges to open the file */
|
||||
|
||||
readonly = ((DIR_GETATTRIBUTES(direntry) & FATATTR_READONLY) != 0);
|
||||
|
@ -69,7 +69,7 @@ static void inode_namecpy(char *dest, const char *src)
|
||||
* Name: inode_alloc
|
||||
****************************************************************************/
|
||||
|
||||
static FAR struct inode *inode_alloc(FAR const char *name)
|
||||
static FAR struct inode *inode_alloc(FAR const char *name, mode_t mode)
|
||||
{
|
||||
FAR struct inode *node;
|
||||
int namelen;
|
||||
@ -78,6 +78,12 @@ static FAR struct inode *inode_alloc(FAR const char *name)
|
||||
node = (FAR struct inode *)kmm_zalloc(FSNODE_SIZE(namelen));
|
||||
if (node)
|
||||
{
|
||||
#ifdef CONFIG_PSEUDOFS_ATTRIBUTES
|
||||
node->i_mode = mode;
|
||||
clock_gettime(CLOCK_REALTIME, &node->i_atime);
|
||||
node->i_mtime = node->i_atime;
|
||||
node->i_ctime = node->i_atime;
|
||||
#endif
|
||||
inode_namecpy(node->i_name, name);
|
||||
}
|
||||
|
||||
@ -128,7 +134,7 @@ static void inode_insert(FAR struct inode *node,
|
||||
|
||||
void inode_root_reserve(void)
|
||||
{
|
||||
g_root_inode = inode_alloc("");
|
||||
g_root_inode = inode_alloc("", 0777);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -140,6 +146,7 @@ void inode_root_reserve(void)
|
||||
*
|
||||
* Input Parameters:
|
||||
* path - The path to the inode to create
|
||||
* mode - inmode privileges
|
||||
* inode - The location to return the inode pointer
|
||||
*
|
||||
* Returned Value:
|
||||
@ -155,7 +162,8 @@ void inode_root_reserve(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int inode_reserve(FAR const char *path, FAR struct inode **inode)
|
||||
int inode_reserve(FAR const char *path,
|
||||
mode_t mode, FAR struct inode **inode)
|
||||
{
|
||||
struct inode_search_s desc;
|
||||
FAR struct inode *left;
|
||||
@ -208,7 +216,7 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode)
|
||||
{
|
||||
/* Insert an operationless node */
|
||||
|
||||
node = inode_alloc(name);
|
||||
node = inode_alloc(name, 0777);
|
||||
if (node != NULL)
|
||||
{
|
||||
inode_insert(node, left, parent);
|
||||
@ -223,7 +231,7 @@ int inode_reserve(FAR const char *path, FAR struct inode **inode)
|
||||
}
|
||||
else
|
||||
{
|
||||
node = inode_alloc(name);
|
||||
node = inode_alloc(name, mode);
|
||||
if (node != NULL)
|
||||
{
|
||||
inode_insert(node, left, parent);
|
||||
|
@ -296,6 +296,7 @@ void inode_root_reserve(void);
|
||||
*
|
||||
* Input Parameters:
|
||||
* path - The path to the inode to create
|
||||
* mode - inmode privileges
|
||||
* inode - The location to return the inode pointer
|
||||
*
|
||||
* Returned Value:
|
||||
@ -308,7 +309,8 @@ void inode_root_reserve(void);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int inode_reserve(FAR const char *path, FAR struct inode **inode);
|
||||
int inode_reserve(FAR const char *path,
|
||||
mode_t mode, FAR struct inode **inode);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: inode_unlink
|
||||
|
@ -374,7 +374,7 @@ int nx_mount(FAR const char *source, FAR const char *target,
|
||||
*/
|
||||
|
||||
{
|
||||
ret = inode_reserve(target, &mountpt_inode);
|
||||
ret = inode_reserve(target, 0777, &mountpt_inode);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* inode_reserve can fail for a couple of reasons, but the most
|
||||
@ -450,9 +450,6 @@ int nx_mount(FAR const char *source, FAR const char *target,
|
||||
INODE_SET_MOUNTPT(mountpt_inode);
|
||||
|
||||
mountpt_inode->u.i_mops = mops;
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
mountpt_inode->i_mode = mode;
|
||||
#endif
|
||||
mountpt_inode->i_private = fshandle;
|
||||
inode_semgive();
|
||||
|
||||
|
@ -274,7 +274,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name,
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
ret = inode_reserve(fullpath, &inode);
|
||||
ret = inode_reserve(fullpath, mode, &inode);
|
||||
inode_semgive();
|
||||
|
||||
if (ret < 0)
|
||||
@ -286,7 +286,7 @@ static int file_mq_vopen(FAR struct file *mq, FAR const char *mq_name,
|
||||
* be created with a reference count of zero.
|
||||
*/
|
||||
|
||||
msgq = (FAR struct mqueue_inode_s *)nxmq_alloc_msgq(mode, attr);
|
||||
msgq = (FAR struct mqueue_inode_s *)nxmq_alloc_msgq(attr);
|
||||
if (!msgq)
|
||||
{
|
||||
ret = -ENOSPC;
|
||||
@ -406,7 +406,7 @@ void nxmq_pollnotify(FAR struct mqueue_inode_s *msgq, pollevent_t eventset)
|
||||
* Optional parameters. When the O_CREAT flag is specified, two optional
|
||||
* parameters are expected:
|
||||
*
|
||||
* 1. mode_t mode (ignored), and
|
||||
* 1. mode_t mode, and
|
||||
* 2. struct mq_attr *attr. The mq_maxmsg attribute
|
||||
* is used at the time that the message queue is
|
||||
* created to determine the maximum number of
|
||||
@ -453,7 +453,7 @@ int file_mq_open(FAR struct file *mq,
|
||||
* Optional parameters. When the O_CREAT flag is specified, two optional
|
||||
* parameters are expected:
|
||||
*
|
||||
* 1. mode_t mode (ignored), and
|
||||
* 1. mode_t mode, and
|
||||
* 2. struct mq_attr *attr. The mq_maxmsg attribute
|
||||
* is used at the time that the message queue is
|
||||
* created to determine the maximum number of
|
||||
@ -495,7 +495,7 @@ mqd_t nxmq_open(FAR const char *mq_name, int oflags, ...)
|
||||
* Optional parameters. When the O_CREAT flag is specified, two optional
|
||||
* parameters are expected:
|
||||
*
|
||||
* 1. mode_t mode (ignored), and
|
||||
* 1. mode_t mode, and
|
||||
* 2. struct mq_attr *attr. The mq_maxmsg attribute
|
||||
* is used at the time that the message queue is
|
||||
* created to determine the maximum number of
|
||||
|
@ -1003,10 +1003,6 @@ int nxffs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
volume = (FAR struct nxffs_volume_s *)filep->f_inode->i_private;
|
||||
DEBUGASSERT(volume != NULL);
|
||||
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
# warning "Missing check for privileges based on inode->i_mode"
|
||||
#endif
|
||||
|
||||
/* Limitation: A file must be opened for reading or writing, but not both.
|
||||
* 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
|
||||
|
@ -225,10 +225,6 @@ static int romfs_open(FAR struct file *filep, FAR const char *relpath,
|
||||
goto errout_with_semaphore;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
# warning "Missing check for privileges based on inode->i_mode"
|
||||
#endif
|
||||
|
||||
/* Create an instance of the file private data to describe the opened
|
||||
* file.
|
||||
*/
|
||||
|
@ -74,7 +74,7 @@
|
||||
* unless one of this name already exists.
|
||||
* Optional parameters. When the O_CREAT flag is specified, two optional
|
||||
* parameters are expected:
|
||||
* 1. mode_t mode (ignored), and
|
||||
* 1. mode_t mode, and
|
||||
* 2. unsigned int value. This initial value of the semaphore. Valid
|
||||
* initial values of the semaphore must be less than or equal to
|
||||
* SEM_VALUE_MAX.
|
||||
@ -178,8 +178,6 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
|
||||
value = va_arg(ap, unsigned);
|
||||
va_end(ap);
|
||||
|
||||
UNUSED(mode);
|
||||
|
||||
/* Check the semaphore value */
|
||||
|
||||
if (value > SEM_VALUE_MAX)
|
||||
@ -199,7 +197,7 @@ FAR sem_t *sem_open (FAR const char *name, int oflags, ...)
|
||||
goto errout_with_lock;
|
||||
}
|
||||
|
||||
ret = inode_reserve(fullpath, &inode);
|
||||
ret = inode_reserve(fullpath, mode, &inode);
|
||||
inode_semgive();
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -2633,7 +2633,7 @@ int unionfs_mount(FAR const char *fspath1, FAR const char *prefix1,
|
||||
* for now, however.
|
||||
*/
|
||||
|
||||
ret = inode_reserve(mountpt, &mpinode);
|
||||
ret = inode_reserve(mountpt, 0777, &mpinode);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* inode_reserve can fail for a couple of reasons, but the most likely
|
||||
@ -2652,10 +2652,7 @@ int unionfs_mount(FAR const char *fspath1, FAR const char *prefix1,
|
||||
|
||||
INODE_SET_MOUNTPT(mpinode);
|
||||
|
||||
mpinode->u.i_mops = &unionfs_operations;
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
mpinode->i_mode = 0755;
|
||||
#endif
|
||||
mpinode->u.i_mops = &unionfs_operations;
|
||||
|
||||
/* Call unionfs_dobind to do the real work. */
|
||||
|
||||
|
@ -137,7 +137,7 @@ int mkdir(const char *pathname, mode_t mode)
|
||||
goto errout_with_search;
|
||||
}
|
||||
|
||||
ret = inode_reserve(pathname, &inode);
|
||||
ret = inode_reserve(pathname, mode, &inode);
|
||||
inode_semgive();
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -51,7 +51,7 @@ static int file_vopen(FAR struct file *filep,
|
||||
{
|
||||
struct inode_search_s desc;
|
||||
FAR struct inode *inode;
|
||||
#if defined(CONFIG_FILE_MODE) || !defined(CONFIG_DISABLE_MOUNTPOINT)
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
mode_t mode = 0666;
|
||||
#endif
|
||||
int ret;
|
||||
@ -61,10 +61,7 @@ static int file_vopen(FAR struct file *filep,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
# ifdef CONFIG_CPP_HAVE_WARNING
|
||||
# warning "File creation not implemented"
|
||||
# endif
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
|
||||
/* If the file is opened for creation, then get the mode bits */
|
||||
|
||||
|
@ -177,7 +177,7 @@ next_subdir:
|
||||
goto errout;
|
||||
}
|
||||
|
||||
ret = inode_reserve(newpath, &newinode);
|
||||
ret = inode_reserve(newpath, 0777, &newinode);
|
||||
if (ret < 0)
|
||||
{
|
||||
/* It is an error if a node at newpath already exists in the tree
|
||||
@ -194,8 +194,13 @@ next_subdir:
|
||||
newinode->i_child = oldinode->i_child; /* Link to lower level inode */
|
||||
newinode->i_flags = oldinode->i_flags; /* Flags for inode */
|
||||
newinode->u.i_ops = oldinode->u.i_ops; /* Inode operations */
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
#ifdef CONFIG_PSEUDOFS_ATTRIBUTES
|
||||
newinode->i_mode = oldinode->i_mode; /* Access mode flags */
|
||||
newinode->i_owner = oldinode->i_owner; /* Owner */
|
||||
newinode->i_group = oldinode->i_group; /* Group */
|
||||
newinode->i_atime = oldinode->i_atime; /* Time of last access */
|
||||
newinode->i_mtime = oldinode->i_mtime; /* Time of last modification */
|
||||
newinode->i_ctime = oldinode->i_ctime; /* Time of last status change */
|
||||
#endif
|
||||
newinode->i_private = oldinode->i_private; /* Per inode driver private data */
|
||||
|
||||
|
@ -348,6 +348,8 @@ int inode_stat(FAR struct inode *inode, FAR struct stat *buf, int resolve)
|
||||
{
|
||||
RESET_BUF(buf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -428,5 +430,14 @@ int inode_stat(FAR struct inode *inode, FAR struct stat *buf, int resolve)
|
||||
buf->st_mode |= S_IFDIR | S_IROTH | S_IRGRP | S_IRUSR;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PSEUDOFS_ATTRIBUTES
|
||||
buf->st_mode |= inode->i_mode;
|
||||
buf->st_uid = inode->i_owner;
|
||||
buf->st_gid = inode->i_group;
|
||||
buf->st_atim = inode->i_atime;
|
||||
buf->st_mtim = inode->i_mtime;
|
||||
buf->st_ctim = inode->i_ctime;
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ int symlink(FAR const char *path1, FAR const char *path2)
|
||||
goto errout_with_search;
|
||||
}
|
||||
|
||||
ret = inode_reserve(path2, &inode);
|
||||
ret = inode_reserve(path2, 0777, &inode);
|
||||
inode_semgive();
|
||||
|
||||
if (ret < 0)
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
@ -353,8 +354,13 @@ struct inode
|
||||
int16_t i_crefs; /* References to inode */
|
||||
uint16_t i_flags; /* Flags for inode */
|
||||
union inode_ops_u u; /* Inode operations */
|
||||
#ifdef CONFIG_FILE_MODE
|
||||
#ifdef CONFIG_PSEUDOFS_ATTRIBUTES
|
||||
mode_t i_mode; /* Access mode flags */
|
||||
uid_t i_owner; /* Owner */
|
||||
gid_t i_group; /* Group */
|
||||
struct timespec i_atime; /* Time of last access */
|
||||
struct timespec i_mtime; /* Time of last modification */
|
||||
struct timespec i_ctime; /* Time of last status change */
|
||||
#endif
|
||||
FAR void *i_private; /* Per inode driver private data */
|
||||
char i_name[1]; /* Name of inode (variable) */
|
||||
@ -492,7 +498,7 @@ void fs_initialize(void);
|
||||
* Input Parameters:
|
||||
* path - The path to the inode to create
|
||||
* fops - The file operations structure
|
||||
* mode - Access privileges (not used)
|
||||
* mode - Access privileges
|
||||
* priv - Private, user data that will be associated with the inode.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -519,7 +525,7 @@ int register_driver(FAR const char *path,
|
||||
* Input Parameters:
|
||||
* path - The path to the inode to create
|
||||
* bops - The block driver operations structure
|
||||
* mode - Access privileges (not used)
|
||||
* mode - Access privileges
|
||||
* priv - Private, user data that will be associated with the inode.
|
||||
*
|
||||
* Returned Value:
|
||||
@ -597,7 +603,7 @@ int unregister_blockdriver(FAR const char *path);
|
||||
* Input Parameters:
|
||||
* path - The path to the inode to create
|
||||
* mtd - The MTD driver structure
|
||||
* mode - inode privileges (not used)
|
||||
* mode - inode privileges
|
||||
* priv - Private, user data that will be associated with the inode.
|
||||
*
|
||||
* Returned Value:
|
||||
|
@ -144,7 +144,7 @@ struct task_group_s; /* Forward reference */
|
||||
* Optional parameters. When the O_CREAT flag is specified, two optional
|
||||
* parameters are expected:
|
||||
*
|
||||
* 1. mode_t mode (ignored), and
|
||||
* 1. mode_t mode, and
|
||||
* 2. struct mq_attr *attr. The mq_maxmsg attribute
|
||||
* is used at the time that the message queue is
|
||||
* created to determine the maximum number of
|
||||
@ -382,7 +382,6 @@ void nxmq_free_msgq(FAR struct mqueue_inode_s *msgq);
|
||||
* It allocates and initializes a struct mqueue_inode_s structure.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mode - mode_t value is ignored
|
||||
* attr - The mq_maxmsg attribute is used at the time that the message
|
||||
* queue is created to determine the maximum number of
|
||||
* messages that may be placed in the message queue.
|
||||
@ -393,8 +392,7 @@ void nxmq_free_msgq(FAR struct mqueue_inode_s *msgq);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct mqueue_inode_s *nxmq_alloc_msgq(mode_t mode,
|
||||
FAR struct mq_attr *attr);
|
||||
FAR struct mqueue_inode_s *nxmq_alloc_msgq(FAR struct mq_attr *attr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nxmq_pollnotify
|
||||
@ -434,7 +432,7 @@ void nxmq_pollnotify(FAR struct mqueue_inode_s *msgq, pollevent_t eventset);
|
||||
* Optional parameters. When the O_CREAT flag is specified, two optional
|
||||
* parameters are expected:
|
||||
*
|
||||
* 1. mode_t mode (ignored), and
|
||||
* 1. mode_t mode, and
|
||||
* 2. struct mq_attr *attr. The mq_maxmsg attribute
|
||||
* is used at the time that the message queue is
|
||||
* created to determine the maximum number of
|
||||
|
@ -46,7 +46,6 @@
|
||||
* It allocates and initializes a struct mqueue_inode_s structure.
|
||||
*
|
||||
* Input Parameters:
|
||||
* mode - mode_t value is ignored
|
||||
* attr - The mq_maxmsg attribute is used at the time that the message
|
||||
* queue is created to determine the maximum number of
|
||||
* messages that may be placed in the message queue.
|
||||
@ -57,8 +56,7 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct mqueue_inode_s *nxmq_alloc_msgq(mode_t mode,
|
||||
FAR struct mq_attr *attr)
|
||||
FAR struct mqueue_inode_s *nxmq_alloc_msgq(FAR struct mq_attr *attr)
|
||||
{
|
||||
FAR struct mqueue_inode_s *msgq;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user