diff --git a/drivers/serial/Make.defs b/drivers/serial/Make.defs index d75e693871..1486d58ab1 100644 --- a/drivers/serial/Make.defs +++ b/drivers/serial/Make.defs @@ -36,12 +36,6 @@ ifeq ($(CONFIG_RPMSG_UART),y) CSRCS += uart_rpmsg.c endif -# termios support - -ifeq ($(CONFIG_SERIAL_TERMIOS),y) - CSRCS += tcdrain.c -endif - # Pseudo-terminal support ifeq ($(CONFIG_PSEUDOTERM),y) diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index ab7d73f865..d9e71bbbe8 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,8 @@ static int uart_putxmitchar(FAR uart_dev_t *dev, int ch, static inline ssize_t uart_irqwrite(FAR uart_dev_t *dev, FAR const char *buffer, size_t buflen); -static int uart_tcdrain(FAR uart_dev_t *dev, clock_t timeout); +static int uart_tcdrain(FAR uart_dev_t *dev, + bool cancelable, clock_t timeout); /* Character driver methods */ @@ -397,10 +399,25 @@ static inline ssize_t uart_irqwrite(FAR uart_dev_t *dev, * ****************************************************************************/ -static int uart_tcdrain(FAR uart_dev_t *dev, clock_t timeout) +static int uart_tcdrain(FAR uart_dev_t *dev, + bool cancelable, clock_t timeout) { int ret; + /* tcdrain is a cancellation point */ + + if (cancelable && enter_cancellation_point()) + { +#ifdef CONFIG_CANCELLATION_POINTS + /* If there is a pending cancellation, then do not perform + * the wait. Exit now with ECANCELED. + */ + + leave_cancellation_point(); + return -ECANCELED; +#endif + } + /* Get exclusive access to the to dev->tmit. We cannot permit new data to * be written while we are trying to flush the old data. * @@ -503,6 +520,11 @@ static int uart_tcdrain(FAR uart_dev_t *dev, clock_t timeout) uart_givesem(&dev->xmit.sem); } + if (cancelable) + { + leave_cancellation_point(); + } + return ret; } @@ -661,7 +683,7 @@ static int uart_close(FAR struct file *filep) { /* Now we wait for the transmit buffer(s) to clear */ - uart_tcdrain(dev, 4 * TICK_PER_SEC); + uart_tcdrain(dev, false, 4 * TICK_PER_SEC); } /* Free the IRQ and disable the UART */ @@ -1366,7 +1388,7 @@ static int uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg) case TCDRN: { - ret = uart_tcdrain(dev, 10 * TICK_PER_SEC); + ret = uart_tcdrain(dev, true, 10 * TICK_PER_SEC); } break; #endif diff --git a/include/sys/syscall_lookup.h b/include/sys/syscall_lookup.h index 47310c2de7..8b677fa22b 100644 --- a/include/sys/syscall_lookup.h +++ b/include/sys/syscall_lookup.h @@ -223,9 +223,6 @@ SYSCALL_LOOKUP(pwrite, 4) SYSCALL_LOOKUP(timerfd_settime, 4) SYSCALL_LOOKUP(timerfd_gettime, 2) #endif -#ifdef CONFIG_SERIAL_TERMIOS - SYSCALL_LOOKUP(tcdrain, 1) -#endif /* Board support */ diff --git a/libs/libc/termios/Make.defs b/libs/libc/termios/Make.defs index 28467581fc..974bc063e0 100644 --- a/libs/libc/termios/Make.defs +++ b/libs/libc/termios/Make.defs @@ -26,7 +26,7 @@ ifeq ($(CONFIG_SERIAL_TERMIOS),y) # Add the termios C files to the build CSRCS += lib_cfspeed.c lib_cfmakeraw.c lib_isatty.c lib_tcflush.c -CSRCS += lib_tcflow.c lib_tcgetattr.c lib_tcsetattr.c +CSRCS += lib_tcdrain.c lib_tcflow.c lib_tcgetattr.c lib_tcsetattr.c CSRCS += lib_ttyname.c lib_ttynamer.c # Add the termios directory to the build diff --git a/drivers/serial/tcdrain.c b/libs/libc/termios/lib_tcdrain.c similarity index 72% rename from drivers/serial/tcdrain.c rename to libs/libc/termios/lib_tcdrain.c index fc896f9bf3..c0e242ab68 100644 --- a/drivers/serial/tcdrain.c +++ b/libs/libc/termios/lib_tcdrain.c @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/serial/tcdrain.c + * libs/libc/termios/lib_tcdrain.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -29,7 +29,6 @@ #include #include -#include #include /**************************************************************************** @@ -54,33 +53,5 @@ int tcdrain(int fd) { - int ret; - - /* tcdrain is a cancellation point */ - - if (enter_cancellation_point()) - { -#ifdef CONFIG_CANCELLATION_POINTS - /* If there is a pending cancellation, then do not perform - * the wait. Exit now with ECANCELED. - */ - - set_errno(ECANCELED); - leave_cancellation_point(); - return ERROR; -#endif - } - - /* Perform the TCDRM IOCTL command. It is safe to use the file descriptor - * in this context because we are executing on the calling application's - * thread. - * - * NOTE: ioctl() will set the errno variable and return ERROR if any error - * occurs. - */ - - ret = ioctl(fd, TCDRN, (unsigned long)0); - - leave_cancellation_point(); - return ret; + return ioctl(fd, TCDRN, (unsigned long)0); } diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 21445cfe54..2a6ae80e9b 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -177,7 +177,6 @@ "task_setcanceltype","sched.h","defined(CONFIG_CANCELLATION_POINTS)","int","int","FAR int *" "task_spawn","nuttx/spawn.h","!defined(CONFIG_BUILD_KERNEL)","int","FAR const char *","main_t","FAR const posix_spawn_file_actions_t *","FAR const posix_spawnattr_t *","FAR char * const []|FAR char * const *","FAR char * const []|FAR char * const *" "task_testcancel","pthread.h","defined(CONFIG_CANCELLATION_POINTS)","void" -"tcdrain","termios.h","defined(CONFIG_SERIAL_TERMIOS)","int","int" "telldir","dirent.h","","off_t","FAR DIR *" "timer_create","time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","clockid_t","FAR struct sigevent *","FAR timer_t *" "timer_delete","time.h","!defined(CONFIG_DISABLE_POSIX_TIMERS)","int","timer_t"