From f7548b934e210ea66e2734c3c6abbddcd1605f11 Mon Sep 17 00:00:00 2001 From: Meco Man <920369182@qq.com> Date: Wed, 20 Oct 2021 21:44:01 -0400 Subject: [posix][dfs] move dfs_posix dfs_poll dfs_select.c to posix folder --- bsp/gd32303e-eval/rtconfig.h | 1 + bsp/lm3s8962/applications/startup.c | 2 +- bsp/lm3s8962/rtconfig.h | 5 +- components/dfs/SConscript | 4 - components/dfs/src/dfs.c | 4 +- components/dfs/src/dfs_file.c | 5 +- components/dfs/src/dfs_poll.c | 235 ------ components/dfs/src/dfs_posix.c | 950 ------------------------ components/dfs/src/dfs_select.c | 183 ----- components/finsh/SConscript | 2 +- components/finsh/finsh.h | 2 +- components/finsh/msh.c | 18 +- components/finsh/msh_file.c | 4 +- components/finsh/shell.c | 16 +- components/finsh/shell.h | 2 +- components/libc/Kconfig | 12 +- components/libc/compilers/common/SConscript | 7 +- components/libc/compilers/common/delay.c | 41 -- components/libc/compilers/common/readme.md | 11 +- components/libc/compilers/common/unistd.c | 119 --- components/libc/posix/aio/SConscript | 4 +- components/libc/posix/getline/SConscript | 2 +- components/libc/posix/mmap/SConscript | 2 +- components/libc/posix/pthreads/SConscript | 2 +- components/libc/posix/signal/SConscript | 2 +- components/libc/posix/src/SConscript | 10 + components/libc/posix/src/delay.c | 50 ++ components/libc/posix/src/poll.c | 230 ++++++ components/libc/posix/src/select.c | 180 +++++ components/libc/posix/src/unistd.c | 1044 +++++++++++++++++++++++++++ components/libc/posix/termios/SConscript | 2 +- include/rtdebug.h | 13 +- 32 files changed, 1565 insertions(+), 1599 deletions(-) delete mode 100644 components/dfs/src/dfs_poll.c delete mode 100644 components/dfs/src/dfs_posix.c delete mode 100644 components/dfs/src/dfs_select.c delete mode 100644 components/libc/compilers/common/delay.c delete mode 100644 components/libc/compilers/common/unistd.c create mode 100644 components/libc/posix/src/SConscript create mode 100644 components/libc/posix/src/delay.c create mode 100644 components/libc/posix/src/poll.c create mode 100644 components/libc/posix/src/select.c create mode 100644 components/libc/posix/src/unistd.c diff --git a/bsp/gd32303e-eval/rtconfig.h b/bsp/gd32303e-eval/rtconfig.h index 7a47c83787..365fd296e0 100644 --- a/bsp/gd32303e-eval/rtconfig.h +++ b/bsp/gd32303e-eval/rtconfig.h @@ -125,6 +125,7 @@ /* POSIX layer and C standard library */ #define RT_USING_LIBC +#define RT_USING_POSIX #define RT_LIBC_USING_TIME #define RT_LIBC_DEFAULT_TIMEZONE 8 /* end of POSIX layer and C standard library */ diff --git a/bsp/lm3s8962/applications/startup.c b/bsp/lm3s8962/applications/startup.c index 87df6e8788..0742c5453c 100644 --- a/bsp/lm3s8962/applications/startup.c +++ b/bsp/lm3s8962/applications/startup.c @@ -119,7 +119,7 @@ void rtthread_startup(void) #ifdef RT_USING_FINSH /* init finsh */ finsh_system_init(); -#ifdef RT_USING_DEVICE +#if !defined(RT_USING_LIBC) && defined(RT_USING_DEVICE) finsh_set_device("uart1"); #endif #endif diff --git a/bsp/lm3s8962/rtconfig.h b/bsp/lm3s8962/rtconfig.h index b154688a6d..dd583205ba 100644 --- a/bsp/lm3s8962/rtconfig.h +++ b/bsp/lm3s8962/rtconfig.h @@ -75,8 +75,10 @@ #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION +#define RT_USING_LIBC #define RT_USING_DFS -/* SECTION: DFS options */ +#define RT_USING_POSIX +#define RT_USING_DFS_DEVFS #define RT_USING_DFS_ELMFAT #define RT_DFS_ELM_WORD_ACCESS @@ -144,6 +146,5 @@ /* the size of each pbuf in the pbuf pool. */ #define RT_LWIP_PBUF_POOL_BUFSIZE 1500 -#define RT_USING_LIBC #define RT_USING_LWIP141 #endif diff --git a/components/dfs/SConscript b/components/dfs/SConscript index e449c84911..5a0b394ce2 100644 --- a/components/dfs/SConscript +++ b/components/dfs/SConscript @@ -5,14 +5,10 @@ src = Split(''' src/dfs.c src/dfs_file.c src/dfs_fs.c -src/dfs_posix.c ''') cwd = GetCurrentDir() CPPPATH = [cwd + "/include"] -if GetDepend('RT_USING_POSIX'): - src += ['src/dfs_poll.c', 'src/dfs_select.c'] - group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS'], CPPPATH = CPPPATH) if GetDepend('RT_USING_DFS'): diff --git a/components/dfs/src/dfs.c b/components/dfs/src/dfs.c index 8155b088f0..fa93afd749 100644 --- a/components/dfs/src/dfs.c +++ b/components/dfs/src/dfs.c @@ -18,7 +18,7 @@ #include #endif -#if defined(RT_USING_DFS_DEVFS) && defined(RT_USING_POSIX) +#ifdef RT_USING_LIBC #include #endif @@ -216,7 +216,7 @@ struct dfs_fd *fd_get(int fd) struct dfs_fd *d; struct dfs_fdtable *fdt; -#if defined(RT_USING_DFS_DEVFS) && defined(RT_USING_POSIX) +#ifdef RT_USING_LIBC if ((0 <= fd) && (fd <= 2)) fd = libc_stdio_get_console(); #endif diff --git a/components/dfs/src/dfs_file.c b/components/dfs/src/dfs_file.c index fa0f6000b4..978c1056c2 100644 --- a/components/dfs/src/dfs_file.c +++ b/components/dfs/src/dfs_file.c @@ -621,6 +621,7 @@ void cat(const char *filename) } FINSH_FUNCTION_EXPORT(cat, print file); +#ifdef RT_USING_POSIX #define BUF_SZ 4096 static void copyfile(const char *src, const char *dst) { @@ -749,6 +750,7 @@ static const char *_get_path_lastname(const char *path) /* skip the '/' then return */ return ++ptr; } + void copy(const char *src, const char *dst) { #define FLAG_SRC_TYPE 0x03 @@ -841,7 +843,8 @@ void copy(const char *src, const char *dst) } } FINSH_FUNCTION_EXPORT(copy, copy file or dir) +#endif /* RT_USING_POSIX */ -#endif +#endif /* RT_USING_FINSH */ /* @} */ diff --git a/components/dfs/src/dfs_poll.c b/components/dfs/src/dfs_poll.c deleted file mode 100644 index 607b3487be..0000000000 --- a/components/dfs/src/dfs_poll.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016-12-28 Bernard first version - * 2018-03-09 Bernard Add protection for pt->triggered. - */ -#include - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef RT_USING_POSIX - -struct rt_poll_node; - -struct rt_poll_table -{ - rt_pollreq_t req; - rt_uint32_t triggered; /* the waited thread whether triggered */ - rt_thread_t polling_thread; - struct rt_poll_node *nodes; -}; - -struct rt_poll_node -{ - struct rt_wqueue_node wqn; - struct rt_poll_table *pt; - struct rt_poll_node *next; -}; - -static int __wqueue_pollwake(struct rt_wqueue_node *wait, void *key) -{ - struct rt_poll_node *pn; - - if (key && !((rt_ubase_t)key & wait->key)) - return -1; - - pn = rt_container_of(wait, struct rt_poll_node, wqn); - pn->pt->triggered = 1; - - return __wqueue_default_wake(wait, key); -} - -static void _poll_add(rt_wqueue_t *wq, rt_pollreq_t *req) -{ - struct rt_poll_table *pt; - struct rt_poll_node *node; - - node = (struct rt_poll_node *)rt_malloc(sizeof(struct rt_poll_node)); - if (node == RT_NULL) - return; - - pt = rt_container_of(req, struct rt_poll_table, req); - - node->wqn.key = req->_key; - rt_list_init(&(node->wqn.list)); - node->wqn.polling_thread = pt->polling_thread; - node->wqn.wakeup = __wqueue_pollwake; - node->next = pt->nodes; - node->pt = pt; - pt->nodes = node; - rt_wqueue_add(wq, &node->wqn); -} - -static void poll_table_init(struct rt_poll_table *pt) -{ - pt->req._proc = _poll_add; - pt->triggered = 0; - pt->nodes = RT_NULL; - pt->polling_thread = rt_thread_self(); -} - -static int poll_wait_timeout(struct rt_poll_table *pt, int msec) -{ - rt_int32_t timeout; - int ret = 0; - struct rt_thread *thread; - rt_base_t level; - - thread = pt->polling_thread; - - timeout = rt_tick_from_millisecond(msec); - - level = rt_hw_interrupt_disable(); - - if (timeout != 0 && !pt->triggered) - { - rt_thread_suspend(thread); - if (timeout > 0) - { - rt_timer_control(&(thread->thread_timer), - RT_TIMER_CTRL_SET_TIME, - &timeout); - rt_timer_start(&(thread->thread_timer)); - } - - rt_hw_interrupt_enable(level); - - rt_schedule(); - - level = rt_hw_interrupt_disable(); - } - - ret = !pt->triggered; - rt_hw_interrupt_enable(level); - - return ret; -} - -static int do_pollfd(struct pollfd *pollfd, rt_pollreq_t *req) -{ - int mask = 0; - int fd; - - fd = pollfd->fd; - - if (fd >= 0) - { - struct dfs_fd *f = fd_get(fd); - mask = POLLNVAL; - - if (f) - { - mask = POLLMASK_DEFAULT; - if (f->fops->poll) - { - req->_key = pollfd->events | POLLERR | POLLHUP; - - mask = f->fops->poll(f, req); - - /* dealwith the device return error -1*/ - if (mask < 0) - { - fd_put(f); - pollfd->revents = 0; - return mask; - } - } - /* Mask out unneeded events. */ - mask &= pollfd->events | POLLERR | POLLHUP; - fd_put(f); - } - } - pollfd->revents = mask; - - return mask; -} - -static int poll_do(struct pollfd *fds, nfds_t nfds, struct rt_poll_table *pt, int msec) -{ - int num; - int istimeout = 0; - int n; - struct pollfd *pf; - int ret = 0; - - if (msec == 0) - { - pt->req._proc = RT_NULL; - istimeout = 1; - } - - while (1) - { - pf = fds; - num = 0; - - for (n = 0; n < nfds; n ++) - { - ret = do_pollfd(pf, &pt->req); - if(ret < 0) - { - /*dealwith the device return error -1 */ - pt->req._proc = RT_NULL; - return ret; - } - else if(ret > 0) - { - num ++; - pt->req._proc = RT_NULL; - } - pf ++; - } - - pt->req._proc = RT_NULL; - - if (num || istimeout) - break; - - if (poll_wait_timeout(pt, msec)) - istimeout = 1; - } - - return num; -} - -static void poll_teardown(struct rt_poll_table *pt) -{ - struct rt_poll_node *node, *next; - - next = pt->nodes; - while (next) - { - node = next; - rt_wqueue_remove(&node->wqn); - next = node->next; - rt_free(node); - } -} - -int poll(struct pollfd *fds, nfds_t nfds, int timeout) -{ - int num; - struct rt_poll_table table; - - poll_table_init(&table); - - num = poll_do(fds, nfds, &table, timeout); - - poll_teardown(&table); - - return num; -} - -#endif diff --git a/components/dfs/src/dfs_posix.c b/components/dfs/src/dfs_posix.c deleted file mode 100644 index acc05fcd53..0000000000 --- a/components/dfs/src/dfs_posix.c +++ /dev/null @@ -1,950 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2009-05-27 Yi.qiu The first version - * 2018-02-07 Bernard Change the 3rd parameter of open/fcntl/ioctl to '...' - */ - -#include -#include -#include "dfs_private.h" - -/** - * @addtogroup FsPosixApi - */ - -/*@{*/ - -/** - * this function is a POSIX compliant version, which will open a file and - * return a file descriptor according specified flags. - * - * @param file the path name of file. - * @param flags the file open flags. - * - * @return the non-negative integer on successful open, others for failed. - */ -int open(const char *file, int flags, ...) -{ - int fd, result; - struct dfs_fd *d; - - /* allocate a fd */ - fd = fd_new(); - if (fd < 0) - { - rt_set_errno(-ENOMEM); - - return -1; - } - d = fd_get(fd); - - result = dfs_file_open(d, file, flags); - if (result < 0) - { - /* release the ref-count of fd */ - fd_put(d); - fd_put(d); - - rt_set_errno(result); - - return -1; - } - - /* release the ref-count of fd */ - fd_put(d); - - return fd; -} -RTM_EXPORT(open); - -/** - * this function is a POSIX compliant version, which will close the open - * file descriptor. - * - * @param fd the file descriptor. - * - * @return 0 on successful, -1 on failed. - */ -int close(int fd) -{ - int result; - struct dfs_fd *d; - - d = fd_get(fd); - if (d == NULL) - { - rt_set_errno(-EBADF); - - return -1; - } - - result = dfs_file_close(d); - fd_put(d); - - if (result < 0) - { - rt_set_errno(result); - - return -1; - } - - fd_put(d); - - return 0; -} -RTM_EXPORT(close); - -/** - * this function is a POSIX compliant version, which will read specified data - * buffer length for an open file descriptor. - * - * @param fd the file descriptor. - * @param buf the buffer to save the read data. - * @param len the maximal length of data buffer - * - * @return the actual read data buffer length. If the returned value is 0, it - * may be reach the end of file, please check errno. - */ -#ifdef _READ_WRITE_RETURN_TYPE -_READ_WRITE_RETURN_TYPE read(int fd, void *buf, size_t len) /* some gcc tool chains will use different data structure */ -#else -ssize_t read(int fd, void *buf, size_t len) -#endif -{ - int result; - struct dfs_fd *d; - - /* get the fd */ - d = fd_get(fd); - if (d == NULL) - { - rt_set_errno(-EBADF); - - return -1; - } - - result = dfs_file_read(d, buf, len); - if (result < 0) - { - fd_put(d); - rt_set_errno(result); - - return -1; - } - - /* release the ref-count of fd */ - fd_put(d); - - return result; -} -RTM_EXPORT(read); - -/** - * this function is a POSIX compliant version, which will write specified data - * buffer length for an open file descriptor. - * - * @param fd the file descriptor - * @param buf the data buffer to be written. - * @param len the data buffer length. - * - * @return the actual written data buffer length. - */ -#ifdef _READ_WRITE_RETURN_TYPE -_READ_WRITE_RETURN_TYPE write(int fd, const void *buf, size_t len) /* some gcc tool chains will use different data structure */ -#else -ssize_t write(int fd, const void *buf, size_t len) -#endif -{ - int result; - struct dfs_fd *d; - - /* get the fd */ - d = fd_get(fd); - if (d == NULL) - { - rt_set_errno(-EBADF); - - return -1; - } - - result = dfs_file_write(d, buf, len); - if (result < 0) - { - fd_put(d); - rt_set_errno(result); - - return -1; - } - - /* release the ref-count of fd */ - fd_put(d); - - return result; -} -RTM_EXPORT(write); - -/** - * this function is a POSIX compliant version, which will seek the offset for - * an open file descriptor. - * - * @param fd the file descriptor. - * @param offset the offset to be seeked. - * @param whence the directory of seek. - * - * @return the current read/write position in the file, or -1 on failed. - */ -off_t lseek(int fd, off_t offset, int whence) -{ - int result; - struct dfs_fd *d; - - d = fd_get(fd); - if (d == NULL) - { - rt_set_errno(-EBADF); - - return -1; - } - - switch (whence) - { - case SEEK_SET: - break; - - case SEEK_CUR: - offset += d->pos; - break; - - case SEEK_END: - offset += d->size; - break; - - default: - fd_put(d); - rt_set_errno(-EINVAL); - - return -1; - } - - if (offset < 0) - { - fd_put(d); - rt_set_errno(-EINVAL); - - return -1; - } - result = dfs_file_lseek(d, offset); - if (result < 0) - { - fd_put(d); - rt_set_errno(result); - - return -1; - } - - /* release the ref-count of fd */ - fd_put(d); - - return offset; -} -RTM_EXPORT(lseek); - -#ifndef _WIN32 /* we can not implement these functions */ -/** - * this function is a POSIX compliant version, which will rename old file name - * to new file name. - * - * @param old the old file name. - * @param new the new file name. - * - * @return 0 on successful, -1 on failed. - * - * note: the old and new file name must be belong to a same file system. - */ -int rename(const char *old_file, const char *new_file) -{ - int result; - - result = dfs_file_rename(old_file, new_file); - if (result < 0) - { - rt_set_errno(result); - - return -1; - } - - return 0; -} -RTM_EXPORT(rename); -#endif - -/** - * this function is a POSIX compliant version, which will unlink (remove) a - * specified path file from file system. - * - * @param pathname the specified path name to be unlinked. - * - * @return 0 on successful, -1 on failed. - */ -int unlink(const char *pathname) -{ - int result; - - result = dfs_file_unlink(pathname); - if (result < 0) - { - rt_set_errno(result); - - return -1; - } - - return 0; -} -RTM_EXPORT(unlink); - -/** - * this function is a POSIX compliant version, which will get file information. - * - * @param file the file name - * @param buf the data buffer to save stat description. - * - * @return 0 on successful, -1 on failed. - */ -int stat(const char *file, struct stat *buf) -{ - int result; - - result = dfs_file_stat(file, buf); - if (result < 0) - { - rt_set_errno(result); - - return -1; - } - - return result; -} -RTM_EXPORT(stat); - -/** - * this function is a POSIX compliant version, which will get file status. - * - * @param fildes the file description - * @param buf the data buffer to save stat description. - * - * @return 0 on successful, -1 on failed. - */ -int fstat(int fildes, struct stat *buf) -{ - struct dfs_fd *d; - - /* get the fd */ - d = fd_get(fildes); - if (d == NULL) - { - rt_set_errno(-EBADF); - - return -1; - } - - /* it's the root directory */ - buf->st_dev = 0; - - buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | - S_IWUSR | S_IWGRP | S_IWOTH; - if (d->type == FT_DIRECTORY) - { - buf->st_mode &= ~S_IFREG; - buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - } - - buf->st_size = d->size; - buf->st_mtime = 0; - - fd_put(d); - - return RT_EOK; -} -RTM_EXPORT(fstat); - -/** - * this function is a POSIX compliant version, which shall request that all data - * for the open file descriptor named by fildes is to be transferred to the storage - * device associated with the file described by fildes. - * - * @param fildes the file description - * - * @return 0 on successful completion. Otherwise, -1 shall be returned and errno - * set to indicate the error. - */ -int fsync(int fildes) -{ - int ret; - struct dfs_fd *d; - - /* get the fd */ - d = fd_get(fildes); - if (d == NULL) - { - rt_set_errno(-EBADF); - return -1; - } - - ret = dfs_file_flush(d); - - fd_put(d); - return ret; -} -RTM_EXPORT(fsync); - -/** - * 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 fcntl(int fildes, int cmd, ...) -{ - int ret = -1; - struct dfs_fd *d; - - /* get the fd */ - d = fd_get(fildes); - if (d) - { - void *arg; - va_list ap; - - va_start(ap, cmd); - arg = va_arg(ap, void *); - va_end(ap); - - ret = dfs_file_ioctl(d, cmd, arg); - fd_put(d); - } - else ret = -EBADF; - - if (ret < 0) - { - rt_set_errno(ret); - ret = -1; - } - - return ret; -} -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 *arg; - va_list ap; - - va_start(ap, cmd); - arg = va_arg(ap, void *); - va_end(ap); - - /* we use fcntl for this API. */ - return fcntl(fildes, cmd, arg); -} -RTM_EXPORT(ioctl); - -/** - * - * this function is a POSIX compliant version, which cause the regular file - * referenced by fd to be truncated to a size of precisely length bytes. - * @param fd the file descriptor. - * @param length the length to be truncated. - * - * @return Upon successful completion, ftruncate() shall return 0; - * otherwise, -1 shall be returned and errno set to indicate the error. - */ -int ftruncate(int fd, off_t length) -{ - int result; - struct dfs_fd *d; - - d = fd_get(fd); - if (d == NULL) - { - rt_set_errno(-EBADF); - - return -1; - } - - if (length < 0) - { - fd_put(d); - rt_set_errno(-EINVAL); - - return -1; - } - result = dfs_file_ftruncate(d, length); - if (result < 0) - { - fd_put(d); - rt_set_errno(result); - - return -1; - } - - /* release the ref-count of fd */ - fd_put(d); - - return 0; -} -RTM_EXPORT(ftruncate); - -/** - * this function is a POSIX compliant version, which will return the - * information about a mounted file system. - * - * @param path the path which mounted file system. - * @param buf the buffer to save the returned information. - * - * @return 0 on successful, others on failed. - */ -int statfs(const char *path, struct statfs *buf) -{ - int result; - - result = dfs_statfs(path, buf); - if (result < 0) - { - rt_set_errno(result); - - return -1; - } - - return result; -} -RTM_EXPORT(statfs); - -/** - * this function is a POSIX compliant version, which will make a directory - * - * @param path the directory path to be made. - * @param mode - * - * @return 0 on successful, others on failed. - */ -int mkdir(const char *path, mode_t mode) -{ - int fd; - struct dfs_fd *d; - int result; - - fd = fd_new(); - if (fd == -1) - { - rt_set_errno(-ENOMEM); - - return -1; - } - - d = fd_get(fd); - - result = dfs_file_open(d, path, O_DIRECTORY | O_CREAT); - - if (result < 0) - { - fd_put(d); - fd_put(d); - rt_set_errno(result); - - return -1; - } - - dfs_file_close(d); - fd_put(d); - fd_put(d); - - return 0; -} -RTM_EXPORT(mkdir); - -#ifdef RT_USING_FINSH -#include -FINSH_FUNCTION_EXPORT(mkdir, create a directory); -#endif - -/** - * this function is a POSIX compliant version, which will remove a directory. - * - * @param pathname the path name to be removed. - * - * @return 0 on successful, others on failed. - */ -int rmdir(const char *pathname) -{ - int result; - - result = dfs_file_unlink(pathname); - if (result < 0) - { - rt_set_errno(result); - - return -1; - } - - return 0; -} -RTM_EXPORT(rmdir); - -/** - * this function is a POSIX compliant version, which will open a directory. - * - * @param name the path name to be open. - * - * @return the DIR pointer of directory, NULL on open directory failed. - */ -DIR *opendir(const char *name) -{ - struct dfs_fd *d; - int fd, result; - DIR *t; - - t = NULL; - - /* allocate a fd */ - fd = fd_new(); - if (fd == -1) - { - rt_set_errno(-ENOMEM); - - return NULL; - } - d = fd_get(fd); - - result = dfs_file_open(d, name, O_RDONLY | O_DIRECTORY); - if (result >= 0) - { - /* open successfully */ - t = (DIR *) rt_malloc(sizeof(DIR)); - if (t == NULL) - { - dfs_file_close(d); - fd_put(d); - } - else - { - memset(t, 0, sizeof(DIR)); - - t->fd = fd; - } - fd_put(d); - - return t; - } - - /* open failed */ - fd_put(d); - fd_put(d); - rt_set_errno(result); - - return NULL; -} -RTM_EXPORT(opendir); - -/** - * this function is a POSIX compliant version, which will return a pointer - * to a dirent structure representing the next directory entry in the - * directory stream. - * - * @param d the directory stream pointer. - * - * @return the next directory entry, NULL on the end of directory or failed. - */ -struct dirent *readdir(DIR *d) -{ - int result; - struct dfs_fd *fd; - - fd = fd_get(d->fd); - if (fd == NULL) - { - rt_set_errno(-EBADF); - return NULL; - } - - if (d->num) - { - struct dirent *dirent_ptr; - dirent_ptr = (struct dirent *)&d->buf[d->cur]; - d->cur += dirent_ptr->d_reclen; - } - - if (!d->num || d->cur >= d->num) - { - /* get a new entry */ - result = dfs_file_getdents(fd, - (struct dirent *)d->buf, - sizeof(d->buf) - 1); - if (result <= 0) - { - fd_put(fd); - rt_set_errno(result); - - return NULL; - } - - d->num = result; - d->cur = 0; /* current entry index */ - } - - fd_put(fd); - - return (struct dirent *)(d->buf + d->cur); -} -RTM_EXPORT(readdir); - -/** - * this function is a POSIX compliant version, which will return current - * location in directory stream. - * - * @param d the directory stream pointer. - * - * @return the current location in directory stream. - */ -long telldir(DIR *d) -{ - struct dfs_fd *fd; - long result; - - fd = fd_get(d->fd); - if (fd == NULL) - { - rt_set_errno(-EBADF); - - return 0; - } - - result = fd->pos - d->num + d->cur; - fd_put(fd); - - return result; -} -RTM_EXPORT(telldir); - -/** - * this function is a POSIX compliant version, which will set position of - * next directory structure in the directory stream. - * - * @param d the directory stream. - * @param offset the offset in directory stream. - */ -void seekdir(DIR *d, off_t offset) -{ - struct dfs_fd *fd; - - fd = fd_get(d->fd); - if (fd == NULL) - { - rt_set_errno(-EBADF); - - return ; - } - - /* seek to the offset position of directory */ - if (dfs_file_lseek(fd, offset) >= 0) - d->num = d->cur = 0; - fd_put(fd); -} -RTM_EXPORT(seekdir); - -/** - * this function is a POSIX compliant version, which will reset directory - * stream. - * - * @param d the directory stream. - */ -void rewinddir(DIR *d) -{ - struct dfs_fd *fd; - - fd = fd_get(d->fd); - if (fd == NULL) - { - rt_set_errno(-EBADF); - - return ; - } - - /* seek to the beginning of directory */ - if (dfs_file_lseek(fd, 0) >= 0) - d->num = d->cur = 0; - fd_put(fd); -} -RTM_EXPORT(rewinddir); - -/** - * this function is a POSIX compliant version, which will close a directory - * stream. - * - * @param d the directory stream. - * - * @return 0 on successful, -1 on failed. - */ -int closedir(DIR *d) -{ - int result; - struct dfs_fd *fd; - - fd = fd_get(d->fd); - if (fd == NULL) - { - rt_set_errno(-EBADF); - - return -1; - } - - result = dfs_file_close(fd); - fd_put(fd); - - fd_put(fd); - rt_free(d); - - if (result < 0) - { - rt_set_errno(result); - - return -1; - } - else - return 0; -} -RTM_EXPORT(closedir); - -#ifdef DFS_USING_WORKDIR -/** - * this function is a POSIX compliant version, which will change working - * directory. - * - * @param path the path name to be changed to. - * - * @return 0 on successful, -1 on failed. - */ -int chdir(const char *path) -{ - char *fullpath; - DIR *d; - - if (path == NULL) - { - dfs_lock(); - rt_kprintf("%s\n", working_directory); - dfs_unlock(); - - return 0; - } - - if (strlen(path) > DFS_PATH_MAX) - { - rt_set_errno(-ENOTDIR); - - return -1; - } - - fullpath = dfs_normalize_path(NULL, path); - if (fullpath == NULL) - { - rt_set_errno(-ENOTDIR); - - return -1; /* build path failed */ - } - - dfs_lock(); - d = opendir(fullpath); - if (d == NULL) - { - rt_free(fullpath); - /* this is a not exist directory */ - dfs_unlock(); - - return -1; - } - - /* close directory stream */ - closedir(d); - - /* copy full path to working directory */ - strncpy(working_directory, fullpath, DFS_PATH_MAX); - /* release normalize directory path name */ - rt_free(fullpath); - - dfs_unlock(); - - return 0; -} -RTM_EXPORT(chdir); - -#ifdef RT_USING_FINSH -FINSH_FUNCTION_EXPORT_ALIAS(chdir, cd, change current working directory); -#endif -#endif - -/** - * this function is a POSIX compliant version, which shall check the file named - * by the pathname pointed to by the path argument for accessibility according - * to the bit pattern contained in amode. - * - * @param path the specified file/dir path. - * @param amode the value is either the bitwise-inclusive OR of the access - * permissions to be checked (R_OK, W_OK, X_OK) or the existence test (F_OK). - */ -int access(const char *path, int amode) -{ - struct stat sb; - if (stat(path, &sb) < 0) - return -1; /* already sets errno */ - - /* ignore R_OK,W_OK,X_OK condition */ - return 0; -} - -/** - * this function is a POSIX compliant version, which will return current - * working directory. - * - * @param buf the returned current directory. - * @param size the buffer size. - * - * @return the returned current directory. - */ -char *getcwd(char *buf, size_t size) -{ -#ifdef DFS_USING_WORKDIR - dfs_lock(); - strncpy(buf, working_directory, size); - dfs_unlock(); -#else - rt_kprintf(NO_WORKING_DIR); -#endif - - return buf; -} -RTM_EXPORT(getcwd); - -/* @} */ diff --git a/components/dfs/src/dfs_select.c b/components/dfs/src/dfs_select.c deleted file mode 100644 index 795b816354..0000000000 --- a/components/dfs/src/dfs_select.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016-12-28 Bernard first version - */ -#include -#include -#include - -#include -#include - -#ifdef RT_USING_POSIX - -static void fdszero(fd_set *set, int nfds) -{ - fd_mask *m; - int n; - - /* - The 'sizeof(fd_set)' of the system space may differ from user space, - so the actual size of the 'fd_set' is determined here with the parameter 'nfds' - */ - m = (fd_mask *)set; - for (n = 0; n < nfds; n += (sizeof(fd_mask) * 8)) - { - rt_memset(m, 0, sizeof(fd_mask)); - m ++; - } -} - -int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) -{ - int fd; - int npfds; - int msec; - int ndx; - int ret; - struct pollfd *pollset = RT_NULL; - - /* How many pollfd structures do we need to allocate? */ - for (fd = 0, npfds = 0; fd < nfds; fd++) - { - /* Check if any monitor operation is requested on this fd */ - if ((readfds && FD_ISSET(fd, readfds)) || - (writefds && FD_ISSET(fd, writefds)) || - (exceptfds && FD_ISSET(fd, exceptfds))) - { - npfds++; - } - } - - /* Allocate the descriptor list for poll() */ - if (npfds > 0) - { - pollset = (struct pollfd *)rt_calloc(npfds, sizeof(struct pollfd)); - if (!pollset) - { - return -1; - } - } - - /* Initialize the descriptor list for poll() */ - for (fd = 0, ndx = 0; fd < nfds; fd++) - { - int incr = 0; - - /* The readfs set holds the set of FDs that the caller can be assured - * of reading from without blocking. Note that POLLHUP is included as - * a read-able condition. POLLHUP will be reported at the end-of-file - * or when a connection is lost. In either case, the read() can then - * be performed without blocking. - */ - - if (readfds && FD_ISSET(fd, readfds)) - { - pollset[ndx].fd = fd; - pollset[ndx].events |= POLLIN; - incr = 1; - } - - if (writefds && FD_ISSET(fd, writefds)) - { - pollset[ndx].fd = fd; - pollset[ndx].events |= POLLOUT; - incr = 1; - } - - if (exceptfds && FD_ISSET(fd, exceptfds)) - { - pollset[ndx].fd = fd; - incr = 1; - } - - ndx += incr; - } - - RT_ASSERT(ndx == npfds); - - /* Convert the timeout to milliseconds */ - if (timeout) - { - msec = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; - } - else - { - msec = -1; - } - - /* Then let poll do all of the real work. */ - - ret = poll(pollset, npfds, msec); - - /* Now set up the return values */ - if (readfds) - { - fdszero(readfds, nfds); - } - - if (writefds) - { - fdszero(writefds, nfds); - } - - if (exceptfds) - { - fdszero(exceptfds, nfds); - } - - /* Convert the poll descriptor list back into selects 3 bitsets */ - - if (ret > 0) - { - ret = 0; - for (ndx = 0; ndx < npfds; ndx++) - { - /* Check for read conditions. Note that POLLHUP is included as a - * read condition. POLLHUP will be reported when no more data will - * be available (such as when a connection is lost). In either - * case, the read() can then be performed without blocking. - */ - - if (readfds) - { - if (pollset[ndx].revents & (POLLIN | POLLHUP)) - { - FD_SET(pollset[ndx].fd, readfds); - ret++; - } - } - - /* Check for write conditions */ - if (writefds) - { - if (pollset[ndx].revents & POLLOUT) - { - FD_SET(pollset[ndx].fd, writefds); - ret++; - } - } - - /* Check for exceptions */ - if (exceptfds) - { - if (pollset[ndx].revents & POLLERR) - { - FD_SET(pollset[ndx].fd, exceptfds); - ret++; - } - } - } - } - - if (pollset) rt_free(pollset); - - return ret; -} - -#endif diff --git a/components/finsh/SConscript b/components/finsh/SConscript index 28fe02bac5..5eabe47c0e 100644 --- a/components/finsh/SConscript +++ b/components/finsh/SConscript @@ -9,7 +9,7 @@ msh.c if GetDepend('MSH_USING_BUILT_IN_COMMANDS'): src += ['cmd.c'] -if GetDepend('RT_USING_DFS'): +if GetDepend('RT_USING_POSIX'): src += ['msh_file.c'] CPPPATH = [cwd] diff --git a/components/finsh/finsh.h b/components/finsh/finsh.h index 98048ebad4..f5e4df9e49 100644 --- a/components/finsh/finsh.h +++ b/components/finsh/finsh.h @@ -169,7 +169,7 @@ extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end; struct finsh_syscall *finsh_syscall_lookup(const char *name); #ifdef RT_USING_DEVICE - void finsh_set_device(const char *device_name); +void finsh_set_device(const char *device_name); #endif #endif diff --git a/components/finsh/msh.c b/components/finsh/msh.c index 18182ca264..5cb54c26e7 100644 --- a/components/finsh/msh.c +++ b/components/finsh/msh.c @@ -21,7 +21,7 @@ #include "msh.h" #include "shell.h" -#ifdef RT_USING_DFS +#ifdef RT_USING_POSIX #include #endif @@ -186,7 +186,7 @@ static cmd_function_t msh_get_cmd(char *cmd, int size) return cmd_func; } -#if defined(RT_USING_MODULE) && defined(RT_USING_DFS) +#if defined(RT_USING_MODULE) && defined(RT_USING_POSIX) /* Return 0 on module executed. Other value indicate error. */ int msh_exec_module(const char *cmd_line, int size) @@ -257,7 +257,7 @@ int msh_exec_module(const char *cmd_line, int size) rt_free(pg_name); return ret; } -#endif /* defined(RT_USING_MODULE) && defined(RT_USING_DFS) */ +#endif /* defined(RT_USING_MODULE) && defined(RT_USING_POSIX) */ static int _msh_exec_cmd(char *cmd, rt_size_t length, int *retp) { @@ -290,7 +290,7 @@ static int _msh_exec_cmd(char *cmd, rt_size_t length, int *retp) return 0; } -#if defined(RT_USING_LWP) && defined(RT_USING_DFS) +#if defined(RT_USING_LWP) && defined(RT_USING_POSIX) static int _msh_exec_lwp(char *cmd, rt_size_t length) { int argc; @@ -350,7 +350,7 @@ int msh_exec(char *cmd, rt_size_t length) { return cmd_ret; } -#ifdef RT_USING_DFS +#ifdef RT_USING_POSIX #ifdef DFS_USING_WORKDIR if (msh_exec_script(cmd, length) == 0) { @@ -371,7 +371,7 @@ int msh_exec(char *cmd, rt_size_t length) return 0; } #endif /* RT_USING_LWP */ -#endif /* RT_USING_DFS */ +#endif /* RT_USING_POSIX */ /* truncate the cmd at the first space. */ { @@ -400,7 +400,7 @@ static int str_common(const char *str1, const char *str2) return (str - str1); } -#ifdef RT_USING_DFS +#ifdef RT_USING_POSIX void msh_auto_complete_path(char *path) { DIR *dir = RT_NULL; @@ -521,7 +521,7 @@ void msh_auto_complete_path(char *path) closedir(dir); rt_free(full_path); } -#endif /* RT_USING_DFS */ +#endif /* RT_USING_POSIX */ void msh_auto_complete(char *prefix) { @@ -538,7 +538,7 @@ void msh_auto_complete(char *prefix) return; } -#ifdef RT_USING_DFS +#ifdef RT_USING_POSIX /* check whether a spare in the command */ { char *ptr; diff --git a/components/finsh/msh_file.c b/components/finsh/msh_file.c index 8f067efd98..4e9ed53b31 100644 --- a/components/finsh/msh_file.c +++ b/components/finsh/msh_file.c @@ -11,7 +11,7 @@ #include -#if defined(RT_USING_FINSH) && defined(RT_USING_DFS) +#if defined(RT_USING_FINSH) && defined(RT_USING_POSIX) #include #include "msh.h" @@ -702,5 +702,5 @@ static int cmd_tail(int argc, char **argv) } MSH_CMD_EXPORT_ALIAS(cmd_tail, tail, print the last N - lines data of the given file); -#endif /* defined(RT_USING_FINSH) && defined(RT_USING_DFS) */ +#endif /* defined(RT_USING_FINSH) && defined(RT_USING_POSIX) */ diff --git a/components/finsh/shell.c b/components/finsh/shell.c index 20f1bdef0f..292ea588cf 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -27,9 +27,9 @@ #include "shell.h" #include "msh.h" -#if defined(RT_USING_DFS) - #include -#endif /* RT_USING_DFS */ +#ifdef RT_USING_POSIX +#include +#endif /* RT_USING_POSIX */ /* finsh thread */ #ifndef RT_USING_HEAP @@ -104,7 +104,7 @@ const char *finsh_get_prompt(void) } strcpy(finsh_prompt, _MSH_PROMPT); -#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR) +#if defined(RT_USING_POSIX) && defined(DFS_USING_WORKDIR) /* get current working directory */ getcwd(&finsh_prompt[rt_strlen(finsh_prompt)], RT_CONSOLEBUF_SIZE - rt_strlen(finsh_prompt)); #endif @@ -145,7 +145,7 @@ void finsh_set_prompt_mode(rt_uint32_t prompt_mode) int finsh_getchar(void) { #ifdef RT_USING_DEVICE -#ifdef RT_USING_POSIX +#ifdef RT_USING_LIBC return getchar(); #else char ch = 0; @@ -163,14 +163,14 @@ int finsh_getchar(void) rt_sem_take(&shell->rx_sem, RT_WAITING_FOREVER); return ch; -#endif /* RT_USING_POSIX */ +#endif /* RT_USING_LIBC */ #else extern char rt_hw_console_getchar(void); return rt_hw_console_getchar(); #endif /* RT_USING_DEVICE */ } -#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE) +#if !defined(RT_USING_LIBC) && defined(RT_USING_DEVICE) static rt_err_t finsh_rx_ind(rt_device_t dev, rt_size_t size) { RT_ASSERT(shell != RT_NULL); @@ -436,7 +436,7 @@ void finsh_thread_entry(void *parameter) shell->echo_mode = 0; #endif -#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE) +#if !defined(RT_USING_LIBC) && defined(RT_USING_DEVICE) /* set console device as shell device */ if (shell->device == RT_NULL) { diff --git a/components/finsh/shell.h b/components/finsh/shell.h index 985d3b3fbd..598596ce00 100644 --- a/components/finsh/shell.h +++ b/components/finsh/shell.h @@ -78,7 +78,7 @@ struct finsh_shell rt_uint16_t line_position; rt_uint16_t line_curpos; -#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE) +#if !defined(RT_USING_LIBC) && defined(RT_USING_DEVICE) rt_device_t device; #endif diff --git a/components/libc/Kconfig b/components/libc/Kconfig index b9600ef389..812b1ce48c 100644 --- a/components/libc/Kconfig +++ b/components/libc/Kconfig @@ -2,6 +2,8 @@ menu "POSIX layer and C standard library" config RT_USING_LIBC bool "Enable libc APIs from toolchain" + select RT_USING_DFS + select RT_USING_POSIX default y config RT_USING_PTHREADS @@ -14,9 +16,9 @@ if RT_USING_PTHREADS default 8 endif -if RT_USING_LIBC && RT_USING_DFS +if RT_USING_DFS config RT_USING_POSIX - bool "Enable POSIX layer for compatibility with UNIX APIs, poll/select etc" + bool "Enable POSIX layer, open/read/write/select etc" select RT_USING_DFS_DEVFS default y @@ -49,9 +51,9 @@ if RT_USING_LIBC default n if RT_USING_MODULE - config RT_USING_CUSTOM_DLMODULE - bool "Enable load dynamic module by custom" - default n + config RT_USING_CUSTOM_DLMODULE + bool "Enable load dynamic module by custom" + default n endif endif diff --git a/components/libc/compilers/common/SConscript b/components/libc/compilers/common/SConscript index b1982aa329..217a447ba6 100644 --- a/components/libc/compilers/common/SConscript +++ b/components/libc/compilers/common/SConscript @@ -6,18 +6,15 @@ src = [] cwd = GetCurrentDir() group = [] CPPPATH = [cwd] +CPPDEFINES = [] if GetDepend('RT_USING_LIBC'): src += Glob('*.c') - if GetDepend('RT_USING_POSIX') == False: - SrcRemove(src, ['unistd.c', 'delay.c']) elif GetDepend('RT_LIBC_USING_TIME'): src += ['time.c'] if rtconfig.CROSS_TOOL == 'keil': - CPPDEFINES = ['__CLK_TCK=RT_TICK_PER_SECOND'] -else: - CPPDEFINES = [] + CPPDEFINES += ['__CLK_TCK=RT_TICK_PER_SECOND'] group = DefineGroup('libc', src, depend = [], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) diff --git a/components/libc/compilers/common/delay.c b/components/libc/compilers/common/delay.c deleted file mode 100644 index 4666258d3b..0000000000 --- a/components/libc/compilers/common/delay.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2021-05-07 Meco Man first Version - */ -#include -#include - -void msleep(unsigned int msecs) -{ - rt_thread_mdelay(msecs); -} -RTM_EXPORT(msleep); - -void ssleep(unsigned int seconds) -{ - msleep(seconds * 1000); -} -RTM_EXPORT(ssleep); - -void mdelay(unsigned long msecs) -{ - rt_hw_us_delay(msecs * 1000); -} -RTM_EXPORT(mdelay); - -void udelay(unsigned long usecs) -{ - rt_hw_us_delay(usecs); -} -RTM_EXPORT(udelay); - -void ndelay(unsigned long nsecs) -{ - rt_hw_us_delay(1); -} -RTM_EXPORT(ndelay); diff --git a/components/libc/compilers/common/readme.md b/components/libc/compilers/common/readme.md index 856ddeb045..82e23f8970 100644 --- a/components/libc/compilers/common/readme.md +++ b/components/libc/compilers/common/readme.md @@ -1,10 +1 @@ -## Attentions - -1. This folder is "common" for all toolchains. - -2. If you want to add new `.c` files, please do not forget to fix SConscript file too. eg: - -```python -if GetDepend('RT_USING_POSIX') == False: - SrcRemove(src, ['unistd.c']) -``` \ No newline at end of file +This folder is "common" for all toolchains. \ No newline at end of file diff --git a/components/libc/compilers/common/unistd.c b/components/libc/compilers/common/unistd.c deleted file mode 100644 index 9a457c4200..0000000000 --- a/components/libc/compilers/common/unistd.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2006-2021, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2020-09-01 Meco Man first Version - * 2021-02-12 Meco Man move all functions located in to this file - */ - -#include -#include -#include - -#ifdef RT_USING_POSIX_TERMIOS -#include "termios.h" -int isatty(int fd) -{ - struct termios ts; - return(tcgetattr(fd, &ts) != -1); /*true if no error (is a tty)*/ -} -#else -int isatty(int fd) -{ - if (fd >=0 && fd < 3) - { - return 1; - } - else - { - return 0; - } -} -#endif -RTM_EXPORT(isatty); - -char *ttyname(int fd) -{ - return "/dev/tty"; /* TODO: need to add more specific */ -} -RTM_EXPORT(ttyname); - -unsigned int sleep(unsigned int seconds) -{ - if (rt_thread_self() != RT_NULL) - { - rt_thread_delay(seconds * RT_TICK_PER_SECOND); - } - else /* scheduler has not run yet */ - { - while(seconds > 0) - { - rt_hw_us_delay(1000000u); - seconds --; - } - } - - return 0; -} -RTM_EXPORT(sleep); - -int usleep(useconds_t usec) -{ - if (rt_thread_self() != RT_NULL) - { - rt_thread_mdelay(usec / 1000u); - } - else /* scheduler has not run yet */ - { - rt_hw_us_delay(usec / 1000u); - } - rt_hw_us_delay(usec % 1000u); - - return 0; -} -RTM_EXPORT(usleep); - -pid_t gettid(void) -{ - /*TODO*/ - return 0; -} - -pid_t getpid(void) -{ - return gettid(); -} -RTM_EXPORT(getpid); - -pid_t getppid(void) -{ - return 0; -} -RTM_EXPORT(getppid); - -uid_t getuid(void) -{ - return 0; /*ROOT*/ -} -RTM_EXPORT(getuid); - -uid_t geteuid(void) -{ - return 0; /*ROOT*/ -} -RTM_EXPORT(geteuid); - -gid_t getgid(void) -{ - return 0; /*ROOT*/ -} -RTM_EXPORT(getgid); - -gid_t getegid(void) -{ - return 0; /*ROOT*/ -} -RTM_EXPORT(getegid); diff --git a/components/libc/posix/aio/SConscript b/components/libc/posix/aio/SConscript index f10462e9c4..445efaade5 100644 --- a/components/libc/posix/aio/SConscript +++ b/components/libc/posix/aio/SConscript @@ -3,9 +3,9 @@ from building import * cwd = GetCurrentDir() -src = Glob('*.c') + Glob('*.cpp') +src = Glob('*.c') CPPPATH = [cwd] -group = DefineGroup('libc', src, depend = ['RT_USING_POSIX', 'RT_USING_POSIX_AIO'], CPPPATH = CPPPATH) +group = DefineGroup('POSIX', src, depend = ['RT_USING_POSIX', 'RT_USING_POSIX_AIO'], CPPPATH = CPPPATH) Return('group') diff --git a/components/libc/posix/getline/SConscript b/components/libc/posix/getline/SConscript index fa4c8618c1..bb18dc04c5 100644 --- a/components/libc/posix/getline/SConscript +++ b/components/libc/posix/getline/SConscript @@ -6,7 +6,7 @@ cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] -group = DefineGroup('libc', src, +group = DefineGroup('POSIX', src, depend = ['RT_USING_LIBC', 'RT_USING_POSIX','RT_USING_POSIX_GETLINE'], CPPPATH = CPPPATH) diff --git a/components/libc/posix/mmap/SConscript b/components/libc/posix/mmap/SConscript index 1a36a15710..fd5b2b953e 100644 --- a/components/libc/posix/mmap/SConscript +++ b/components/libc/posix/mmap/SConscript @@ -6,7 +6,7 @@ cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] -group = DefineGroup('libc', src, +group = DefineGroup('POSIX', src, depend = ['RT_USING_DFS', 'RT_USING_POSIX_MMAP'], CPPPATH = CPPPATH) diff --git a/components/libc/posix/pthreads/SConscript b/components/libc/posix/pthreads/SConscript index 767b406d4c..7cd78300b2 100644 --- a/components/libc/posix/pthreads/SConscript +++ b/components/libc/posix/pthreads/SConscript @@ -16,7 +16,7 @@ try: except : pass -group = DefineGroup('libc', src, +group = DefineGroup('POSIX', src, depend = ['RT_USING_PTHREADS', 'RT_USING_LIBC'], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES) Return('group') diff --git a/components/libc/posix/signal/SConscript b/components/libc/posix/signal/SConscript index f07ff58f6e..07cd98cbe0 100644 --- a/components/libc/posix/signal/SConscript +++ b/components/libc/posix/signal/SConscript @@ -6,7 +6,7 @@ cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] -group = DefineGroup('libc', src, +group = DefineGroup('POSIX', src, depend = ['RT_USING_SIGNALS', 'RT_USING_PTHREADS', 'RT_USING_LIBC'], CPPPATH = CPPPATH) diff --git a/components/libc/posix/src/SConscript b/components/libc/posix/src/SConscript new file mode 100644 index 0000000000..5640181ac5 --- /dev/null +++ b/components/libc/posix/src/SConscript @@ -0,0 +1,10 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = Glob('*.c') + +group = DefineGroup('POSIX', src, depend = ['RT_USING_POSIX']) + +Return('group') diff --git a/components/libc/posix/src/delay.c b/components/libc/posix/src/delay.c new file mode 100644 index 0000000000..1638caafbf --- /dev/null +++ b/components/libc/posix/src/delay.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-07 Meco Man first Version + */ +#include +#include +#define DBG_TAG "POSIX.delay" +#define DBG_LVL DBG_INFO +#include + +RT_WEAK void rt_hw_us_delay(rt_uint32_t us) +{ + (void) us; + LOG_W("Please consider implementing rt_hw_us_delay() in another file."); +} + +void msleep(unsigned int msecs) +{ + rt_thread_mdelay(msecs); +} +RTM_EXPORT(msleep); + +void ssleep(unsigned int seconds) +{ + msleep(seconds * 1000); +} +RTM_EXPORT(ssleep); + +void mdelay(unsigned long msecs) +{ + rt_hw_us_delay(msecs * 1000); +} +RTM_EXPORT(mdelay); + +void udelay(unsigned long usecs) +{ + rt_hw_us_delay(usecs); +} +RTM_EXPORT(udelay); + +void ndelay(unsigned long nsecs) +{ + rt_hw_us_delay(1); +} +RTM_EXPORT(ndelay); diff --git a/components/libc/posix/src/poll.c b/components/libc/posix/src/poll.c new file mode 100644 index 0000000000..2109fb310b --- /dev/null +++ b/components/libc/posix/src/poll.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2016-12-28 Bernard first version + * 2018-03-09 Bernard Add protection for pt->triggered. + */ +#include +#include +#include +#include +#include + +#ifdef RT_USING_POSIX + +struct rt_poll_node; + +struct rt_poll_table +{ + rt_pollreq_t req; + rt_uint32_t triggered; /* the waited thread whether triggered */ + rt_thread_t polling_thread; + struct rt_poll_node *nodes; +}; + +struct rt_poll_node +{ + struct rt_wqueue_node wqn; + struct rt_poll_table *pt; + struct rt_poll_node *next; +}; + +static int __wqueue_pollwake(struct rt_wqueue_node *wait, void *key) +{ + struct rt_poll_node *pn; + + if (key && !((rt_ubase_t)key & wait->key)) + return -1; + + pn = rt_container_of(wait, struct rt_poll_node, wqn); + pn->pt->triggered = 1; + + return __wqueue_default_wake(wait, key); +} + +static void _poll_add(rt_wqueue_t *wq, rt_pollreq_t *req) +{ + struct rt_poll_table *pt; + struct rt_poll_node *node; + + node = (struct rt_poll_node *)rt_malloc(sizeof(struct rt_poll_node)); + if (node == RT_NULL) + return; + + pt = rt_container_of(req, struct rt_poll_table, req); + + node->wqn.key = req->_key; + rt_list_init(&(node->wqn.list)); + node->wqn.polling_thread = pt->polling_thread; + node->wqn.wakeup = __wqueue_pollwake; + node->next = pt->nodes; + node->pt = pt; + pt->nodes = node; + rt_wqueue_add(wq, &node->wqn); +} + +static void poll_table_init(struct rt_poll_table *pt) +{ + pt->req._proc = _poll_add; + pt->triggered = 0; + pt->nodes = RT_NULL; + pt->polling_thread = rt_thread_self(); +} + +static int poll_wait_timeout(struct rt_poll_table *pt, int msec) +{ + rt_int32_t timeout; + int ret = 0; + struct rt_thread *thread; + rt_base_t level; + + thread = pt->polling_thread; + + timeout = rt_tick_from_millisecond(msec); + + level = rt_hw_interrupt_disable(); + + if (timeout != 0 && !pt->triggered) + { + rt_thread_suspend(thread); + if (timeout > 0) + { + rt_timer_control(&(thread->thread_timer), + RT_TIMER_CTRL_SET_TIME, + &timeout); + rt_timer_start(&(thread->thread_timer)); + } + + rt_hw_interrupt_enable(level); + + rt_schedule(); + + level = rt_hw_interrupt_disable(); + } + + ret = !pt->triggered; + rt_hw_interrupt_enable(level); + + return ret; +} + +static int do_pollfd(struct pollfd *pollfd, rt_pollreq_t *req) +{ + int mask = 0; + int fd; + + fd = pollfd->fd; + + if (fd >= 0) + { + struct dfs_fd *f = fd_get(fd); + mask = POLLNVAL; + + if (f) + { + mask = POLLMASK_DEFAULT; + if (f->fops->poll) + { + req->_key = pollfd->events | POLLERR | POLLHUP; + + mask = f->fops->poll(f, req); + + /* dealwith the device return error -1*/ + if (mask < 0) + { + fd_put(f); + pollfd->revents = 0; + return mask; + } + } + /* Mask out unneeded events. */ + mask &= pollfd->events | POLLERR | POLLHUP; + fd_put(f); + } + } + pollfd->revents = mask; + + return mask; +} + +static int poll_do(struct pollfd *fds, nfds_t nfds, struct rt_poll_table *pt, int msec) +{ + int num; + int istimeout = 0; + int n; + struct pollfd *pf; + int ret = 0; + + if (msec == 0) + { + pt->req._proc = RT_NULL; + istimeout = 1; + } + + while (1) + { + pf = fds; + num = 0; + + for (n = 0; n < nfds; n ++) + { + ret = do_pollfd(pf, &pt->req); + if(ret < 0) + { + /*dealwith the device return error -1 */ + pt->req._proc = RT_NULL; + return ret; + } + else if(ret > 0) + { + num ++; + pt->req._proc = RT_NULL; + } + pf ++; + } + + pt->req._proc = RT_NULL; + + if (num || istimeout) + break; + + if (poll_wait_timeout(pt, msec)) + istimeout = 1; + } + + return num; +} + +static void poll_teardown(struct rt_poll_table *pt) +{ + struct rt_poll_node *node, *next; + + next = pt->nodes; + while (next) + { + node = next; + rt_wqueue_remove(&node->wqn); + next = node->next; + rt_free(node); + } +} + +int poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + int num; + struct rt_poll_table table; + + poll_table_init(&table); + + num = poll_do(fds, nfds, &table, timeout); + + poll_teardown(&table); + + return num; +} + +#endif diff --git a/components/libc/posix/src/select.c b/components/libc/posix/src/select.c new file mode 100644 index 0000000000..25cda0f0d1 --- /dev/null +++ b/components/libc/posix/src/select.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2016-12-28 Bernard first version + */ +#include +#include +#include + +#ifdef RT_USING_POSIX + +static void fdszero(fd_set *set, int nfds) +{ + fd_mask *m; + int n; + + /* + The 'sizeof(fd_set)' of the system space may differ from user space, + so the actual size of the 'fd_set' is determined here with the parameter 'nfds' + */ + m = (fd_mask *)set; + for (n = 0; n < nfds; n += (sizeof(fd_mask) * 8)) + { + rt_memset(m, 0, sizeof(fd_mask)); + m ++; + } +} + +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) +{ + int fd; + int npfds; + int msec; + int ndx; + int ret; + struct pollfd *pollset = RT_NULL; + + /* How many pollfd structures do we need to allocate? */ + for (fd = 0, npfds = 0; fd < nfds; fd++) + { + /* Check if any monitor operation is requested on this fd */ + if ((readfds && FD_ISSET(fd, readfds)) || + (writefds && FD_ISSET(fd, writefds)) || + (exceptfds && FD_ISSET(fd, exceptfds))) + { + npfds++; + } + } + + /* Allocate the descriptor list for poll() */ + if (npfds > 0) + { + pollset = (struct pollfd *)rt_calloc(npfds, sizeof(struct pollfd)); + if (!pollset) + { + return -1; + } + } + + /* Initialize the descriptor list for poll() */ + for (fd = 0, ndx = 0; fd < nfds; fd++) + { + int incr = 0; + + /* The readfs set holds the set of FDs that the caller can be assured + * of reading from without blocking. Note that POLLHUP is included as + * a read-able condition. POLLHUP will be reported at the end-of-file + * or when a connection is lost. In either case, the read() can then + * be performed without blocking. + */ + + if (readfds && FD_ISSET(fd, readfds)) + { + pollset[ndx].fd = fd; + pollset[ndx].events |= POLLIN; + incr = 1; + } + + if (writefds && FD_ISSET(fd, writefds)) + { + pollset[ndx].fd = fd; + pollset[ndx].events |= POLLOUT; + incr = 1; + } + + if (exceptfds && FD_ISSET(fd, exceptfds)) + { + pollset[ndx].fd = fd; + incr = 1; + } + + ndx += incr; + } + + RT_ASSERT(ndx == npfds); + + /* Convert the timeout to milliseconds */ + if (timeout) + { + msec = timeout->tv_sec * 1000 + timeout->tv_usec / 1000; + } + else + { + msec = -1; + } + + /* Then let poll do all of the real work. */ + + ret = poll(pollset, npfds, msec); + + /* Now set up the return values */ + if (readfds) + { + fdszero(readfds, nfds); + } + + if (writefds) + { + fdszero(writefds, nfds); + } + + if (exceptfds) + { + fdszero(exceptfds, nfds); + } + + /* Convert the poll descriptor list back into selects 3 bitsets */ + + if (ret > 0) + { + ret = 0; + for (ndx = 0; ndx < npfds; ndx++) + { + /* Check for read conditions. Note that POLLHUP is included as a + * read condition. POLLHUP will be reported when no more data will + * be available (such as when a connection is lost). In either + * case, the read() can then be performed without blocking. + */ + + if (readfds) + { + if (pollset[ndx].revents & (POLLIN | POLLHUP)) + { + FD_SET(pollset[ndx].fd, readfds); + ret++; + } + } + + /* Check for write conditions */ + if (writefds) + { + if (pollset[ndx].revents & POLLOUT) + { + FD_SET(pollset[ndx].fd, writefds); + ret++; + } + } + + /* Check for exceptions */ + if (exceptfds) + { + if (pollset[ndx].revents & POLLERR) + { + FD_SET(pollset[ndx].fd, exceptfds); + ret++; + } + } + } + } + + if (pollset) rt_free(pollset); + + return ret; +} + +#endif diff --git a/components/libc/posix/src/unistd.c b/components/libc/posix/src/unistd.c new file mode 100644 index 0000000000..ef2df2c2fe --- /dev/null +++ b/components/libc/posix/src/unistd.c @@ -0,0 +1,1044 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2020-09-01 Meco Man first Version + * 2021-02-12 Meco Man move all functions located in to this file + */ +#include +#include +#include +#include +#include +#include + +/** + * this function is a POSIX compliant version, which will open a file and + * return a file descriptor according specified flags. + * + * @param file the path name of file. + * @param flags the file open flags. + * + * @return the non-negative integer on successful open, others for failed. + */ +int open(const char *file, int flags, ...) +{ + int fd, result; + struct dfs_fd *d; + + /* allocate a fd */ + fd = fd_new(); + if (fd < 0) + { + rt_set_errno(-ENOMEM); + + return -1; + } + d = fd_get(fd); + + result = dfs_file_open(d, file, flags); + if (result < 0) + { + /* release the ref-count of fd */ + fd_put(d); + fd_put(d); + + rt_set_errno(result); + + return -1; + } + + /* release the ref-count of fd */ + fd_put(d); + + return fd; +} +RTM_EXPORT(open); + +/** + * this function is a POSIX compliant version, which will close the open + * file descriptor. + * + * @param fd the file descriptor. + * + * @return 0 on successful, -1 on failed. + */ +int close(int fd) +{ + int result; + struct dfs_fd *d; + + d = fd_get(fd); + if (d == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + result = dfs_file_close(d); + fd_put(d); + + if (result < 0) + { + rt_set_errno(result); + + return -1; + } + + fd_put(d); + + return 0; +} +RTM_EXPORT(close); + +/** + * this function is a POSIX compliant version, which will read specified data + * buffer length for an open file descriptor. + * + * @param fd the file descriptor. + * @param buf the buffer to save the read data. + * @param len the maximal length of data buffer + * + * @return the actual read data buffer length. If the returned value is 0, it + * may be reach the end of file, please check errno. + */ +#ifdef _READ_WRITE_RETURN_TYPE +_READ_WRITE_RETURN_TYPE read(int fd, void *buf, size_t len) /* some gcc tool chains will use different data structure */ +#else +ssize_t read(int fd, void *buf, size_t len) +#endif +{ + int result; + struct dfs_fd *d; + + /* get the fd */ + d = fd_get(fd); + if (d == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + result = dfs_file_read(d, buf, len); + if (result < 0) + { + fd_put(d); + rt_set_errno(result); + + return -1; + } + + /* release the ref-count of fd */ + fd_put(d); + + return result; +} +RTM_EXPORT(read); + +/** + * this function is a POSIX compliant version, which will write specified data + * buffer length for an open file descriptor. + * + * @param fd the file descriptor + * @param buf the data buffer to be written. + * @param len the data buffer length. + * + * @return the actual written data buffer length. + */ +#ifdef _READ_WRITE_RETURN_TYPE +_READ_WRITE_RETURN_TYPE write(int fd, const void *buf, size_t len) /* some gcc tool chains will use different data structure */ +#else +ssize_t write(int fd, const void *buf, size_t len) +#endif +{ + int result; + struct dfs_fd *d; + + /* get the fd */ + d = fd_get(fd); + if (d == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + result = dfs_file_write(d, buf, len); + if (result < 0) + { + fd_put(d); + rt_set_errno(result); + + return -1; + } + + /* release the ref-count of fd */ + fd_put(d); + + return result; +} +RTM_EXPORT(write); + +/** + * this function is a POSIX compliant version, which will seek the offset for + * an open file descriptor. + * + * @param fd the file descriptor. + * @param offset the offset to be seeked. + * @param whence the directory of seek. + * + * @return the current read/write position in the file, or -1 on failed. + */ +off_t lseek(int fd, off_t offset, int whence) +{ + int result; + struct dfs_fd *d; + + d = fd_get(fd); + if (d == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + switch (whence) + { + case SEEK_SET: + break; + + case SEEK_CUR: + offset += d->pos; + break; + + case SEEK_END: + offset += d->size; + break; + + default: + fd_put(d); + rt_set_errno(-EINVAL); + + return -1; + } + + if (offset < 0) + { + fd_put(d); + rt_set_errno(-EINVAL); + + return -1; + } + result = dfs_file_lseek(d, offset); + if (result < 0) + { + fd_put(d); + rt_set_errno(result); + + return -1; + } + + /* release the ref-count of fd */ + fd_put(d); + + return offset; +} +RTM_EXPORT(lseek); + +#ifndef _WIN32 /* we can not implement these functions */ +/** + * this function is a POSIX compliant version, which will rename old file name + * to new file name. + * + * @param old the old file name. + * @param new the new file name. + * + * @return 0 on successful, -1 on failed. + * + * note: the old and new file name must be belong to a same file system. + */ +int rename(const char *old_file, const char *new_file) +{ + int result; + + result = dfs_file_rename(old_file, new_file); + if (result < 0) + { + rt_set_errno(result); + + return -1; + } + + return 0; +} +RTM_EXPORT(rename); +#endif + +/** + * this function is a POSIX compliant version, which will unlink (remove) a + * specified path file from file system. + * + * @param pathname the specified path name to be unlinked. + * + * @return 0 on successful, -1 on failed. + */ +int unlink(const char *pathname) +{ + int result; + + result = dfs_file_unlink(pathname); + if (result < 0) + { + rt_set_errno(result); + + return -1; + } + + return 0; +} +RTM_EXPORT(unlink); + +/** + * this function is a POSIX compliant version, which will get file information. + * + * @param file the file name + * @param buf the data buffer to save stat description. + * + * @return 0 on successful, -1 on failed. + */ +int stat(const char *file, struct stat *buf) +{ + int result; + + result = dfs_file_stat(file, buf); + if (result < 0) + { + rt_set_errno(result); + + return -1; + } + + return result; +} +RTM_EXPORT(stat); + +/** + * this function is a POSIX compliant version, which will get file status. + * + * @param fildes the file description + * @param buf the data buffer to save stat description. + * + * @return 0 on successful, -1 on failed. + */ +int fstat(int fildes, struct stat *buf) +{ + struct dfs_fd *d; + + /* get the fd */ + d = fd_get(fildes); + if (d == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + /* it's the root directory */ + buf->st_dev = 0; + + buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | + S_IWUSR | S_IWGRP | S_IWOTH; + if (d->type == FT_DIRECTORY) + { + buf->st_mode &= ~S_IFREG; + buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; + } + + buf->st_size = d->size; + buf->st_mtime = 0; + + fd_put(d); + + return RT_EOK; +} +RTM_EXPORT(fstat); + +/** + * this function is a POSIX compliant version, which shall request that all data + * for the open file descriptor named by fildes is to be transferred to the storage + * device associated with the file described by fildes. + * + * @param fildes the file description + * + * @return 0 on successful completion. Otherwise, -1 shall be returned and errno + * set to indicate the error. + */ +int fsync(int fildes) +{ + int ret; + struct dfs_fd *d; + + /* get the fd */ + d = fd_get(fildes); + if (d == NULL) + { + rt_set_errno(-EBADF); + return -1; + } + + ret = dfs_file_flush(d); + + fd_put(d); + return ret; +} +RTM_EXPORT(fsync); + +/** + * 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 fcntl(int fildes, int cmd, ...) +{ + int ret = -1; + struct dfs_fd *d; + + /* get the fd */ + d = fd_get(fildes); + if (d) + { + void *arg; + va_list ap; + + va_start(ap, cmd); + arg = va_arg(ap, void *); + va_end(ap); + + ret = dfs_file_ioctl(d, cmd, arg); + fd_put(d); + } + else ret = -EBADF; + + if (ret < 0) + { + rt_set_errno(ret); + ret = -1; + } + + return ret; +} +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 *arg; + va_list ap; + + va_start(ap, cmd); + arg = va_arg(ap, void *); + va_end(ap); + + /* we use fcntl for this API. */ + return fcntl(fildes, cmd, arg); +} +RTM_EXPORT(ioctl); + +/** + * + * this function is a POSIX compliant version, which cause the regular file + * referenced by fd to be truncated to a size of precisely length bytes. + * @param fd the file descriptor. + * @param length the length to be truncated. + * + * @return Upon successful completion, ftruncate() shall return 0; + * otherwise, -1 shall be returned and errno set to indicate the error. + */ +int ftruncate(int fd, off_t length) +{ + int result; + struct dfs_fd *d; + + d = fd_get(fd); + if (d == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + if (length < 0) + { + fd_put(d); + rt_set_errno(-EINVAL); + + return -1; + } + result = dfs_file_ftruncate(d, length); + if (result < 0) + { + fd_put(d); + rt_set_errno(result); + + return -1; + } + + /* release the ref-count of fd */ + fd_put(d); + + return 0; +} +RTM_EXPORT(ftruncate); + +/** + * this function is a POSIX compliant version, which will return the + * information about a mounted file system. + * + * @param path the path which mounted file system. + * @param buf the buffer to save the returned information. + * + * @return 0 on successful, others on failed. + */ +int statfs(const char *path, struct statfs *buf) +{ + int result; + + result = dfs_statfs(path, buf); + if (result < 0) + { + rt_set_errno(result); + + return -1; + } + + return result; +} +RTM_EXPORT(statfs); + +/** + * this function is a POSIX compliant version, which will make a directory + * + * @param path the directory path to be made. + * @param mode + * + * @return 0 on successful, others on failed. + */ +int mkdir(const char *path, mode_t mode) +{ + int fd; + struct dfs_fd *d; + int result; + + fd = fd_new(); + if (fd == -1) + { + rt_set_errno(-ENOMEM); + + return -1; + } + + d = fd_get(fd); + + result = dfs_file_open(d, path, O_DIRECTORY | O_CREAT); + + if (result < 0) + { + fd_put(d); + fd_put(d); + rt_set_errno(result); + + return -1; + } + + dfs_file_close(d); + fd_put(d); + fd_put(d); + + return 0; +} +RTM_EXPORT(mkdir); + +/** + * this function is a POSIX compliant version, which will remove a directory. + * + * @param pathname the path name to be removed. + * + * @return 0 on successful, others on failed. + */ +int rmdir(const char *pathname) +{ + int result; + + result = dfs_file_unlink(pathname); + if (result < 0) + { + rt_set_errno(result); + + return -1; + } + + return 0; +} +RTM_EXPORT(rmdir); + +/** + * this function is a POSIX compliant version, which will open a directory. + * + * @param name the path name to be open. + * + * @return the DIR pointer of directory, NULL on open directory failed. + */ +DIR *opendir(const char *name) +{ + struct dfs_fd *d; + int fd, result; + DIR *t; + + t = NULL; + + /* allocate a fd */ + fd = fd_new(); + if (fd == -1) + { + rt_set_errno(-ENOMEM); + + return NULL; + } + d = fd_get(fd); + + result = dfs_file_open(d, name, O_RDONLY | O_DIRECTORY); + if (result >= 0) + { + /* open successfully */ + t = (DIR *) rt_malloc(sizeof(DIR)); + if (t == NULL) + { + dfs_file_close(d); + fd_put(d); + } + else + { + memset(t, 0, sizeof(DIR)); + + t->fd = fd; + } + fd_put(d); + + return t; + } + + /* open failed */ + fd_put(d); + fd_put(d); + rt_set_errno(result); + + return NULL; +} +RTM_EXPORT(opendir); + +/** + * this function is a POSIX compliant version, which will return a pointer + * to a dirent structure representing the next directory entry in the + * directory stream. + * + * @param d the directory stream pointer. + * + * @return the next directory entry, NULL on the end of directory or failed. + */ +struct dirent *readdir(DIR *d) +{ + int result; + struct dfs_fd *fd; + + fd = fd_get(d->fd); + if (fd == NULL) + { + rt_set_errno(-EBADF); + return NULL; + } + + if (d->num) + { + struct dirent *dirent_ptr; + dirent_ptr = (struct dirent *)&d->buf[d->cur]; + d->cur += dirent_ptr->d_reclen; + } + + if (!d->num || d->cur >= d->num) + { + /* get a new entry */ + result = dfs_file_getdents(fd, + (struct dirent *)d->buf, + sizeof(d->buf) - 1); + if (result <= 0) + { + fd_put(fd); + rt_set_errno(result); + + return NULL; + } + + d->num = result; + d->cur = 0; /* current entry index */ + } + + fd_put(fd); + + return (struct dirent *)(d->buf + d->cur); +} +RTM_EXPORT(readdir); + +/** + * this function is a POSIX compliant version, which will return current + * location in directory stream. + * + * @param d the directory stream pointer. + * + * @return the current location in directory stream. + */ +long telldir(DIR *d) +{ + struct dfs_fd *fd; + long result; + + fd = fd_get(d->fd); + if (fd == NULL) + { + rt_set_errno(-EBADF); + + return 0; + } + + result = fd->pos - d->num + d->cur; + fd_put(fd); + + return result; +} +RTM_EXPORT(telldir); + +/** + * this function is a POSIX compliant version, which will set position of + * next directory structure in the directory stream. + * + * @param d the directory stream. + * @param offset the offset in directory stream. + */ +void seekdir(DIR *d, off_t offset) +{ + struct dfs_fd *fd; + + fd = fd_get(d->fd); + if (fd == NULL) + { + rt_set_errno(-EBADF); + + return ; + } + + /* seek to the offset position of directory */ + if (dfs_file_lseek(fd, offset) >= 0) + d->num = d->cur = 0; + fd_put(fd); +} +RTM_EXPORT(seekdir); + +/** + * this function is a POSIX compliant version, which will reset directory + * stream. + * + * @param d the directory stream. + */ +void rewinddir(DIR *d) +{ + struct dfs_fd *fd; + + fd = fd_get(d->fd); + if (fd == NULL) + { + rt_set_errno(-EBADF); + + return ; + } + + /* seek to the beginning of directory */ + if (dfs_file_lseek(fd, 0) >= 0) + d->num = d->cur = 0; + fd_put(fd); +} +RTM_EXPORT(rewinddir); + +/** + * this function is a POSIX compliant version, which will close a directory + * stream. + * + * @param d the directory stream. + * + * @return 0 on successful, -1 on failed. + */ +int closedir(DIR *d) +{ + int result; + struct dfs_fd *fd; + + fd = fd_get(d->fd); + if (fd == NULL) + { + rt_set_errno(-EBADF); + + return -1; + } + + result = dfs_file_close(fd); + fd_put(fd); + + fd_put(fd); + rt_free(d); + + if (result < 0) + { + rt_set_errno(result); + + return -1; + } + else + return 0; +} +RTM_EXPORT(closedir); + +#ifdef DFS_USING_WORKDIR +/** + * this function is a POSIX compliant version, which will change working + * directory. + * + * @param path the path name to be changed to. + * + * @return 0 on successful, -1 on failed. + */ +int chdir(const char *path) +{ + char *fullpath; + DIR *d; + + if (path == NULL) + { + dfs_lock(); + rt_kprintf("%s\n", working_directory); + dfs_unlock(); + + return 0; + } + + if (strlen(path) > DFS_PATH_MAX) + { + rt_set_errno(-ENOTDIR); + + return -1; + } + + fullpath = dfs_normalize_path(NULL, path); + if (fullpath == NULL) + { + rt_set_errno(-ENOTDIR); + + return -1; /* build path failed */ + } + + dfs_lock(); + d = opendir(fullpath); + if (d == NULL) + { + rt_free(fullpath); + /* this is a not exist directory */ + dfs_unlock(); + + return -1; + } + + /* close directory stream */ + closedir(d); + + /* copy full path to working directory */ + strncpy(working_directory, fullpath, DFS_PATH_MAX); + /* release normalize directory path name */ + rt_free(fullpath); + + dfs_unlock(); + + return 0; +} +RTM_EXPORT(chdir); + +#ifdef RT_USING_FINSH +FINSH_FUNCTION_EXPORT_ALIAS(chdir, cd, change current working directory); +#endif +#endif + +/** + * this function is a POSIX compliant version, which shall check the file named + * by the pathname pointed to by the path argument for accessibility according + * to the bit pattern contained in amode. + * + * @param path the specified file/dir path. + * @param amode the value is either the bitwise-inclusive OR of the access + * permissions to be checked (R_OK, W_OK, X_OK) or the existence test (F_OK). + */ +int access(const char *path, int amode) +{ + struct stat sb; + if (stat(path, &sb) < 0) + return -1; /* already sets errno */ + + /* ignore R_OK,W_OK,X_OK condition */ + return 0; +} + +/** + * this function is a POSIX compliant version, which will return current + * working directory. + * + * @param buf the returned current directory. + * @param size the buffer size. + * + * @return the returned current directory. + */ +char *getcwd(char *buf, size_t size) +{ +#ifdef DFS_USING_WORKDIR + dfs_lock(); + strncpy(buf, working_directory, size); + dfs_unlock(); +#else + rt_kprintf(NO_WORKING_DIR); +#endif + + return buf; +} +RTM_EXPORT(getcwd); + +#ifdef RT_USING_POSIX_TERMIOS +#include "termios.h" +int isatty(int fd) +{ + struct termios ts; + return(tcgetattr(fd, &ts) != -1); /*true if no error (is a tty)*/ +} +#else +int isatty(int fd) +{ + if (fd >=0 && fd < 3) + { + return 1; + } + else + { + return 0; + } +} +#endif +RTM_EXPORT(isatty); + +char *ttyname(int fd) +{ + return "/dev/tty"; /* TODO: need to add more specific */ +} +RTM_EXPORT(ttyname); + +unsigned int sleep(unsigned int seconds) +{ + if (rt_thread_self() != RT_NULL) + { + ssleep(seconds); + } + else /* scheduler has not run yet */ + { + while(seconds > 0) + { + udelay(1000000u); + seconds --; + } + } + + return 0; +} +RTM_EXPORT(sleep); + +int usleep(useconds_t usec) +{ + if (rt_thread_self() != RT_NULL) + { + msleep(usec / 1000u); + } + else /* scheduler has not run yet */ + { + udelay(usec / 1000u); + } + udelay(usec % 1000u); + + return 0; +} +RTM_EXPORT(usleep); + +pid_t gettid(void) +{ + /*TODO*/ + return 0; +} + +pid_t getpid(void) +{ + return gettid(); +} +RTM_EXPORT(getpid); + +pid_t getppid(void) +{ + return 0; +} +RTM_EXPORT(getppid); + +uid_t getuid(void) +{ + return 0; /*ROOT*/ +} +RTM_EXPORT(getuid); + +uid_t geteuid(void) +{ + return 0; /*ROOT*/ +} +RTM_EXPORT(geteuid); + +gid_t getgid(void) +{ + return 0; /*ROOT*/ +} +RTM_EXPORT(getgid); + +gid_t getegid(void) +{ + return 0; /*ROOT*/ +} +RTM_EXPORT(getegid); diff --git a/components/libc/posix/termios/SConscript b/components/libc/posix/termios/SConscript index 381eb5ad8b..bd9a528461 100644 --- a/components/libc/posix/termios/SConscript +++ b/components/libc/posix/termios/SConscript @@ -6,7 +6,7 @@ cwd = GetCurrentDir() src = Glob('*.c') + Glob('*.cpp') CPPPATH = [cwd] -group = DefineGroup('libc', src, +group = DefineGroup('POSIX', src, depend = ['RT_USING_LIBC', 'RT_USING_POSIX', 'RT_USING_POSIX_TERMIOS'], CPPPATH = CPPPATH) diff --git a/include/rtdebug.h b/include/rtdebug.h index 8c7d450ad4..c170d148c1 100644 --- a/include/rtdebug.h +++ b/include/rtdebug.h @@ -17,18 +17,7 @@ #if !defined(RT_USING_DFS) || !defined(RT_USING_DFS_DEVFS) #error "POSIX poll/select, stdin need file system(RT_USING_DFS) and device file system(RT_USING_DFS_DEVFS)" #endif - -#if !defined(RT_USING_LIBC) -#error "POSIX layer need standard C library(RT_USING_LIBC)" -#endif - -#endif - -#ifdef RT_USING_POSIX_TERMIOS -#if !defined(RT_USING_POSIX) -#error "termios need POSIX layer(RT_USING_POSIX)" -#endif -#endif +#endif /* RT_USING_POSIX */ /* Using this macro to control all kernel debug features. */ #ifdef RT_DEBUG -- cgit v1.3.1