diff --git a/components/dfs/include/dfs_posix.h b/components/dfs/include/dfs_posix.h index b0fe2041ab..9b2ff25b80 100644 --- a/components/dfs/include/dfs_posix.h +++ b/components/dfs/include/dfs_posix.h @@ -22,6 +22,7 @@ * 2009-05-27 Yi.qiu The first version. * 2010-07-18 Bernard add stat and statfs structure definitions. * 2011-05-16 Yi.qiu Change parameter name of rename, "new" is C++ key word. + * 2017-12-27 Bernard Add fcntl API. */ #ifndef __DFS_POSIX_H__ @@ -66,6 +67,7 @@ int unlink(const char *pathname); int stat(const char *file, struct stat *buf); int fstat(int fildes, struct stat *buf); int fsync(int fildes); +int fcntl(int fildes, int cmd, void *data); int ioctl(int fildes, int cmd, void *data); /* directory api*/ diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c index 8ebccac2a5..c437b43829 100644 --- a/components/dfs/src/dfs_file.c +++ b/components/dfs/src/dfs_file.c @@ -173,9 +173,29 @@ int dfs_file_close(struct dfs_fd *fd) */ int dfs_file_ioctl(struct dfs_fd *fd, int cmd, void *args) { - if (fd == NULL || fd->type != FT_REGULAR) + if (fd == NULL) return -EINVAL; + /* regular file system fd */ + if (fd->type == FT_REGULAR) + { + switch (cmd) + { + case F_GETFL: + return fd->flags; /* return flags */ + case F_SETFL: + { + int flags = (int)args; + int mask = O_NONBLOCK | O_APPEND; + + flags &= mask; + fd->flags &= mask; + fd->flags |= flags; + } + return 0; + } + } + if (fd->fops->ioctl != NULL) return fd->fops->ioctl(fd, cmd, args); diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c index ff3acb874e..c257dfd6c4 100644 --- a/components/dfs/src/dfs_posix.c +++ b/components/dfs/src/dfs_posix.c @@ -428,28 +428,46 @@ RTM_EXPORT(fsync); * @return 0 on successful completion. Otherwise, -1 shall be returned and errno * set to indicate the error. */ -int ioctl(int fildes, int cmd, void *data) +int fcntl(int fildes, int cmd, void *data) { - int ret; + int ret = -1; struct dfs_fd *d; /* get the fd */ d = fd_get(fildes); - if (d == NULL) + if (d) { - rt_set_errno(-EBADF); - return -1; + ret = dfs_file_ioctl(d, cmd, data); + fd_put(d); } + else ret = -EBADF; - ret = dfs_file_ioctl(d, cmd, data); if (ret != 0) { rt_set_errno(ret); ret = -1; } - fd_put(d); - return ret; + return 0; +} +RTM_EXPORT(fcntl); + +/** + * this function is a POSIX compliant version, which shall perform a variety of + * control functions on devices. + * + * @param fildes the file description + * @param cmd the specified command + * @param data represents the additional information that is needed by this + * specific device to perform the requested function. + * + * @return 0 on successful completion. Otherwise, -1 shall be returned and errno + * set to indicate the error. + */ +int ioctl(int fildes, int cmd, void *data) +{ + /* we use fcntl for this API. */ + return fcntl(fildes, cmd, data); } RTM_EXPORT(ioctl); diff --git a/include/libc/libc_fcntl.h b/include/libc/libc_fcntl.h index fd61b44273..f8dd66c7fd 100644 --- a/include/libc/libc_fcntl.h +++ b/include/libc/libc_fcntl.h @@ -16,6 +16,13 @@ #define O_ACCMODE (_O_RDONLY | _O_WRONLY | _O_RDWR) #endif +#ifndef F_GETFL +#define F_GETFL 3 +#endif +#ifndef F_SETFL +#define F_SETFL 4 +#endif + #else #define O_RDONLY 00 #define O_WRONLY 01