diff --git a/drivers/pipes/fifo.c b/drivers/pipes/fifo.c index 938708c41e2..2ff13232e54 100644 --- a/drivers/pipes/fifo.c +++ b/drivers/pipes/fifo.c @@ -106,7 +106,7 @@ int nx_mkfifo(FAR const char *pathname, mode_t mode, size_t bufsize) return -ENOMEM; } - ret = register_driver(pathname, &g_fifo_fops, mode, (FAR void *)dev); + ret = register_pipedriver(pathname, &g_fifo_fops, mode, (FAR void *)dev); if (ret != 0) { pipecommon_freedev(dev); diff --git a/drivers/pipes/pipe.c b/drivers/pipes/pipe.c index ab3220ebf4b..8f2c4e8ea25 100644 --- a/drivers/pipes/pipe.c +++ b/drivers/pipes/pipe.c @@ -171,7 +171,7 @@ static int pipe_register(size_t bufsize, int flags, /* Register the pipe device */ - ret = register_driver(devname, &g_pipe_fops, 0666, (FAR void *)dev); + ret = register_pipedriver(devname, &g_pipe_fops, 0666, (FAR void *)dev); if (ret != 0) { pipecommon_freedev(dev); @@ -251,14 +251,14 @@ int file_pipe(FAR struct file *filep[2], size_t bufsize, int flags) /* Remove the pipe name from file system */ - unregister_driver(devname); + unregister_pipedriver(devname); return OK; errout_with_wrfd: file_close(filep[1]); errout_with_driver: - unregister_driver(devname); + unregister_pipedriver(devname); return ret; } @@ -329,14 +329,14 @@ int pipe2(int fd[2], int flags) /* Remove the pipe name from file system */ - unregister_driver(devname); + unregister_pipedriver(devname); return OK; errout_with_wrfd: nx_close(fd[1]); errout_with_driver: - unregister_driver(devname); + unregister_pipedriver(devname); return ERROR; } diff --git a/drivers/pipes/pipe_common.h b/drivers/pipes/pipe_common.h index c94193e6e43..1e587a2c960 100644 --- a/drivers/pipes/pipe_common.h +++ b/drivers/pipes/pipe_common.h @@ -37,17 +37,6 @@ * Pre-processor Definitions ****************************************************************************/ -/* Pipe/FIFO support */ - -#ifndef CONFIG_PIPES -# undef CONFIG_DEV_PIPE_MAXSIZE -# undef CONFIG_DEV_PIPE_SIZE -# undef CONFIG_DEV_FIFO_SIZE -# define CONFIG_DEV_PIPE_MAXSIZE 0 -# define CONFIG_DEV_PIPE_SIZE 0 -# define CONFIG_DEV_FIFO_SIZE 0 -#endif - /* Pipe/FIFO size */ #ifndef CONFIG_DEV_PIPE_MAXSIZE @@ -70,6 +59,17 @@ # define CONFIG_DEV_FIFO_SIZE 1024 #endif +/* Pipe/FIFO support */ + +#ifndef CONFIG_PIPES +# undef CONFIG_DEV_PIPE_MAXSIZE +# undef CONFIG_DEV_PIPE_SIZE +# undef CONFIG_DEV_FIFO_SIZE +# define CONFIG_DEV_PIPE_MAXSIZE 0 +# define CONFIG_DEV_PIPE_SIZE 0 +# define CONFIG_DEV_FIFO_SIZE 0 +#endif + /* Maximum number of threads than can be waiting for POLL events */ #ifndef CONFIG_DEV_PIPE_NPOLLWAITERS diff --git a/fs/driver/CMakeLists.txt b/fs/driver/CMakeLists.txt index 18b3f97da0c..30056cd659f 100644 --- a/fs/driver/CMakeLists.txt +++ b/fs/driver/CMakeLists.txt @@ -18,7 +18,8 @@ # # ############################################################################## -set(SRCS fs_registerdriver.c fs_unregisterdriver.c) +set(SRCS fs_registerdriver.c fs_unregisterdriver.c fs_registerpipedriver.c + fs_unregisterpipedriver.c) # Don't built-in block driver support if there are no mountpoints diff --git a/fs/driver/Make.defs b/fs/driver/Make.defs index 330f559b10a..e0e9fcf5d93 100644 --- a/fs/driver/Make.defs +++ b/fs/driver/Make.defs @@ -19,6 +19,7 @@ ############################################################################ CSRCS += fs_registerdriver.c fs_unregisterdriver.c +CSRCS += fs_registerpipedriver.c fs_unregisterpipedriver.c # Don't built-in block driver support if there are no mountpoints diff --git a/fs/driver/fs_registerpipedriver.c b/fs/driver/fs_registerpipedriver.c new file mode 100644 index 00000000000..031d4c66f87 --- /dev/null +++ b/fs/driver/fs_registerpipedriver.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * fs/driver/fs_registerpipedriver.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +#include "inode/inode.h" + +#ifdef CONFIG_PIPES + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: register_pipedriver + * + * Description: + * Register a pipe driver inode the pseudo file system. + * + * Input Parameters: + * path - The path to the inode to create + * fops - The file operations structure + * mode - inmode privileges + * priv - Private, user data that will be associated with the inode. + * + * Returned Value: + * Zero on success (with the inode point in 'inode'); A negated errno + * value is returned on a failure (all error values returned by + * inode_reserve): + * + * EINVAL - 'path' is invalid for this operation + * EEXIST - An inode already exists at 'path' + * ENOMEM - Failed to allocate in-memory resources for the operation + * + ****************************************************************************/ + +int register_pipedriver(FAR const char *path, + FAR const struct file_operations *fops, + mode_t mode, FAR void *priv) +{ + FAR struct inode *node; + int ret; + + /* Insert a dummy node -- we need to hold the inode semaphore because we + * will have a momentarily bad structure. + */ + + ret = inode_lock(); + if (ret < 0) + { + return ret; + } + + ret = inode_reserve(path, mode, &node); + if (ret >= 0) + { + /* We have it, now populate it with driver specific information. + * NOTE that the initial reference count on the new inode is zero. + */ + + INODE_SET_PIPE(node); + + node->u.i_ops = fops; + node->i_private = priv; + ret = OK; + } + + inode_unlock(); + return ret; +} + +#endif /* CONFIG_PIPES */ diff --git a/fs/driver/fs_unregisterpipedriver.c b/fs/driver/fs_unregisterpipedriver.c new file mode 100644 index 00000000000..c8253ca6930 --- /dev/null +++ b/fs/driver/fs_unregisterpipedriver.c @@ -0,0 +1,59 @@ +/**************************************************************************** + * fs/driver/fs_unregisterpipedriver.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include "inode/inode.h" + +#ifdef CONFIG_PIPES + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: unregister_pipedriver + * + * Description: + * Remove the pipe driver inode at 'path' from the pseudo-file system + * + ****************************************************************************/ + +int unregister_pipedriver(FAR const char *path) +{ + int ret; + + ret = inode_lock(); + if (ret >= 0) + { + ret = inode_remove(path); + inode_unlock(); + } + + return ret; +} + +#endif /* CONFIG_PIPES */ diff --git a/fs/vfs/fs_dir.c b/fs/vfs/fs_dir.c index d2cb4c5c3c1..fc78f619feb 100644 --- a/fs/vfs/fs_dir.c +++ b/fs/vfs/fs_dir.c @@ -355,6 +355,10 @@ static int read_pseudodir(FAR struct fs_dirent_s *dir, { entry->d_type = DTYPE_SHM; } + else if (INODE_IS_PIPE(pdir->next)) + { + entry->d_type = DTYPE_FIFO; + } } /* If the node has child node(s) or no operations, then we will say that diff --git a/fs/vfs/fs_open.c b/fs/vfs/fs_open.c index b2119a7ba71..d5c0e6a3621 100644 --- a/fs/vfs/fs_open.c +++ b/fs/vfs/fs_open.c @@ -188,7 +188,7 @@ static int file_vopen(FAR struct file *filep, FAR const char *path, } } #endif - else if (INODE_IS_DRIVER(inode)) + else if (INODE_IS_DRIVER(inode) || INODE_IS_PIPE(inode)) { if (inode->u.i_ops->open != NULL) { diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index 267a542da52..9660e951ece 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -307,7 +307,7 @@ int file_poll(FAR struct file *filep, FAR struct pollfd *fds, bool setup) */ if ((INODE_IS_DRIVER(inode) || INODE_IS_MQUEUE(inode) || - INODE_IS_SOCKET(inode)) && + INODE_IS_SOCKET(inode) || INODE_IS_PIPE(inode)) && inode->u.i_ops != NULL && inode->u.i_ops->poll != NULL) { /* Yes, it does... Setup the poll */ diff --git a/fs/vfs/fs_stat.c b/fs/vfs/fs_stat.c index f61b1816119..e6acc398580 100644 --- a/fs/vfs/fs_stat.c +++ b/fs/vfs/fs_stat.c @@ -360,7 +360,15 @@ int inode_stat(FAR struct inode *inode, FAR struct stat *buf, int resolve) } else #endif +#if defined(CONFIG_PIPES) + /* Check for pipes */ + if (INODE_IS_PIPE(inode)) + { + buf->st_mode = S_IRWXO | S_IRWXG | S_IRWXU | S_IFIFO; + } + else +#endif /* Handle "normal inodes */ if (inode->u.i_ops != NULL) diff --git a/fs/vfs/fs_unlink.c b/fs/vfs/fs_unlink.c index 515f577ff8f..4844803afc2 100644 --- a/fs/vfs/fs_unlink.c +++ b/fs/vfs/fs_unlink.c @@ -123,8 +123,8 @@ int nx_unlink(FAR const char *pathname) * release all resources because it is no longer accessible. */ - if ((INODE_IS_DRIVER(inode) || INODE_IS_SHM(inode)) && - inode->u.i_ops->unlink) + if ((INODE_IS_DRIVER(inode) || INODE_IS_SHM(inode) || + INODE_IS_PIPE(inode)) && inode->u.i_ops->unlink) { /* Notify the character driver that it has been unlinked */ diff --git a/include/nuttx/fs/fs.h b/include/nuttx/fs/fs.h index 6f06f072e30..fd6e0157bff 100644 --- a/include/nuttx/fs/fs.h +++ b/include/nuttx/fs/fs.h @@ -114,6 +114,7 @@ #define FSNODEFLAG_TYPE_MTD 0x00000007 /* Named MTD driver */ #define FSNODEFLAG_TYPE_SOFTLINK 0x00000008 /* Soft link */ #define FSNODEFLAG_TYPE_SOCKET 0x00000009 /* Socket */ +#define FSNODEFLAG_TYPE_PIPE 0x0000000a /* Pipe */ #define FSNODEFLAG_DELETED 0x00000010 /* Unlinked */ #define INODE_IS_TYPE(i,t) \ @@ -129,6 +130,7 @@ #define INODE_IS_MTD(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_MTD) #define INODE_IS_SOFTLINK(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK) #define INODE_IS_SOCKET(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_SOCKET) +#define INODE_IS_PIPE(i) INODE_IS_TYPE(i,FSNODEFLAG_TYPE_PIPE) #define INODE_GET_TYPE(i) ((i)->i_flags & FSNODEFLAG_TYPE_MASK) #define INODE_SET_TYPE(i,t) \ @@ -147,6 +149,7 @@ #define INODE_SET_MTD(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_MTD) #define INODE_SET_SOFTLINK(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOFTLINK) #define INODE_SET_SOCKET(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_SOCKET) +#define INODE_SET_PIPE(i) INODE_SET_TYPE(i,FSNODEFLAG_TYPE_PIPE) /* The status change flags. * These should be or-ed together to figure out what want to change. @@ -718,6 +721,47 @@ int register_mtdpartition(FAR const char *partition, int unregister_mtddriver(FAR const char *path); #endif +#ifdef CONFIG_PIPES + +/**************************************************************************** + * Name: register_pipedriver + * + * Description: + * Register a pipe driver inode the pseudo file system. + * + * Input Parameters: + * path - The path to the inode to create + * fops - The file operations structure + * mode - inmode privileges + * priv - Private, user data that will be associated with the inode. + * + * Returned Value: + * Zero on success (with the inode point in 'inode'); A negated errno + * value is returned on a failure (all error values returned by + * inode_reserve): + * + * EINVAL - 'path' is invalid for this operation + * EEXIST - An inode already exists at 'path' + * ENOMEM - Failed to allocate in-memory resources for the operation + * + ****************************************************************************/ + +int register_pipedriver(FAR const char *path, + FAR const struct file_operations *fops, + mode_t mode, FAR void *priv); + +/**************************************************************************** + * Name: unregister_pipedriver + * + * Description: + * Remove the pipe driver inode at 'path' from the pseudo-file system + * + ****************************************************************************/ + +int unregister_pipedriver(FAR const char *path); + +#endif /* CONFIG_PIPES */ + /**************************************************************************** * Name: nx_mount *