diff --git a/TODO b/TODO index ad169165c2..64cc683d12 100644 --- a/TODO +++ b/TODO @@ -530,7 +530,7 @@ o pthreads (sched/pthreads) NA clock_nanosleep() NA msgsnd() read() sigwaitinfo() close() NA msync() NA readv() 01 sleep() connect() nanosleep() recv() 02 system() - -- creat() open() recvfrom() NA tcdrain() + -- creat() open() recvfrom() tcdrain() fcntl() pause() NA recvmsg() 01 usleep() NA fdatasync() poll() select() -- wait() fsync() pread() sem_timedwait() waitid() diff --git a/arch/arm/src/lc823450/Kconfig b/arch/arm/src/lc823450/Kconfig index 8d7c18d220..7866de57f6 100644 --- a/arch/arm/src/lc823450/Kconfig +++ b/arch/arm/src/lc823450/Kconfig @@ -7,27 +7,22 @@ comment "LC823450 Configuration Options" menu "LC823450 Peripheral Support" -config SERIAL_TERMIOS - bool "Serial driver TERMIOS supported" - default n - ---help--- - Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.). - If this is not defined, then the terminal settings (baud, parity, etc). - are not configurable at runtime; serial streams cannot be flushed, etc.. - config LC823450_UART0 bool "UART0" select UART0_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS default n config LC823450_UART1 bool "UART1" select UART1_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS default n config LC823450_UART2 bool "UART2" select UART2_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS default n config LC823450_WDT diff --git a/arch/arm/src/lpc11xx/Kconfig b/arch/arm/src/lpc11xx/Kconfig index 088188c950..f85cc994cd 100644 --- a/arch/arm/src/lpc11xx/Kconfig +++ b/arch/arm/src/lpc11xx/Kconfig @@ -56,6 +56,7 @@ config LPC11_PLL config LPC11_UART0 bool "UART0" select UART0_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS default y config LPC11_CAN0 @@ -100,20 +101,6 @@ config LPC11_FLASH endmenu -menu "Serial driver options" - depends on LPC11_UART0 || LPC11_UART1 || LPC11_UART2 || LPC11_UART3 || LPC11_UART4 - -config SERIAL_TERMIOS - bool "Serial driver TERMIOS supported" - depends on LPC11_UART0 || LPC11_UART1 || LPC11_UART2 || LPC11_UART3 - default n - ---help--- - Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.). - If this is not defined, then the terminal settings (baud, parity, etc). - are not configurable at runtime; serial streams cannot be flushed, etc.. - -endmenu - menu "ADC driver options" depends on LPC11_ADC diff --git a/arch/avr/src/atmega/Kconfig b/arch/avr/src/atmega/Kconfig index 2d2c4d813a..1079d13128 100644 --- a/arch/avr/src/atmega/Kconfig +++ b/arch/avr/src/atmega/Kconfig @@ -32,24 +32,12 @@ menu "ATMega Peripheral Selections" config AVR_USART0 bool "USART0" select USART0_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS config AVR_USART1 bool "USART1" select USART1_SERIALDRIVER + select ARCH_HAVE_SERIAL_TERMIOS endmenu # ATMega Peripheral Selections - -menu "Low level USART driver options" - depends on AVR_USART0 || AVR_USART1 - -config SERIAL_TERMIOS - bool "Serial driver TERMIOS supported" - depends on AVR_USART0 || AVR_USART1 - default n - ---help--- - Serial driver supports termios.h interfaces (tcsetattr, tcflush, etc.). - If this is not defined, then the terminal settings (baud, parity, etc). - are not configurable at runtime; serial streams cannot be flushed, etc.. - -endmenu endif diff --git a/drivers/serial/Make.defs b/drivers/serial/Make.defs index e7cc43426d..f1e5020b7e 100644 --- a/drivers/serial/Make.defs +++ b/drivers/serial/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # drivers/serial/Make.defs # -# Copyright (C) 2009, 2011 Gregory Nutt. All rights reserved. +# Copyright (C) 2009, 2011, 2017 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -47,6 +47,12 @@ ifeq ($(CONFIG_16550_UART),y) CSRCS += uart_16550.c endif +# termios support + +ifeq ($(CONFIG_SERIAL_TERMIOS),y) + CSRCS += tcdrain.c +endif + # Pseudo-terminal support ifeq ($(CONFIG_PSEUDOTERM),y) diff --git a/libc/termios/lib_tcdrain.c b/drivers/serial/tcdrain.c similarity index 79% rename from libc/termios/lib_tcdrain.c rename to drivers/serial/tcdrain.c index 755442261c..1dcdf456bb 100644 --- a/libc/termios/lib_tcdrain.c +++ b/drivers/serial/tcdrain.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/termios/lib_tcdrain.c + * drivers/serial/tcdrain.c * * Copyright (C) 2017 Gregory Nutt. All rights reserved. * Copyright (C) 2017 Sebastien Lorquet. All rights reserved. @@ -45,6 +45,7 @@ #include #include +#include #include /**************************************************************************** @@ -68,5 +69,33 @@ int tcdrain(int fd) { - return ioctl(fd, TCDRN, (unsigned long)0); + 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 is any error + * occurs. + */ + + ret = ioctl(fd, TCDRN, (unsigned long)0); + + leave_cancellation_point(); + return ret; } diff --git a/include/sys/syscall.h b/include/sys/syscall.h index feff102939..b468fdd3e1 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -298,9 +298,15 @@ # ifndef CONFIG_DISABLE_POLL # define SYS_poll __SYS_poll # define SYS_select (__SYS_poll+1) -# define __SYS_boardctl (__SYS_poll+2) +# define __SYS_termios (__SYS_poll+2) # else -# define __SYS_boardctl __SYS_poll +# define __SYS_termios __SYS_poll +# endif +# ifndef CONFIG_SERIAL_TERMIOS +# define SYS_tcdrain __SYS_termios +# define __SYS_boardctl (__SYS_termios+1) +# else +# define __SYS_boardctl __SYS_termios # endif #else # define __SYS_boardctl __SYS_descriptors diff --git a/libc/termios/Make.defs b/libc/termios/Make.defs index e04adce65e..91a4c4a6b6 100644 --- a/libc/termios/Make.defs +++ b/libc/termios/Make.defs @@ -42,7 +42,7 @@ ifeq ($(CONFIG_SERIAL_TERMIOS),y) # Add the termios C files to the build CSRCS += lib_cfgetspeed.c lib_cfsetspeed.c lib_isatty.c lib_tcflush.c -CSRCS += lib_tcgetattr.c lib_tcsetattr.c lib_tcdrain.c +CSRCS += lib_tcgetattr.c lib_tcsetattr.c # Add the termios directory to the build diff --git a/syscall/syscall.csv b/syscall/syscall.csv index b5efe96510..22e1f0490a 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -153,6 +153,7 @@ "task_setcancelstate","sched.h","","int","int","FAR int*" "task_setcanceltype","sched.h","defined(CONFIG_CANCELLATION_POINTS)","int","int","FAR int*" "task_testcancel","pthread.h","defined(CONFIG_CANCELLATION_POINTS)","void" +"tcdrain","termios.h","defined(CONFIG_SERIAL_TERMIOS)","int","int" "telldir","dirent.h","CONFIG_NFILE_DESCRIPTORS > 0","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" diff --git a/syscall/syscall_funclookup.c b/syscall/syscall_funclookup.c index 8e62470103..8e7009b90e 100644 --- a/syscall/syscall_funclookup.c +++ b/syscall/syscall_funclookup.c @@ -72,6 +72,7 @@ #include #include #include +#include #include /* Errno access is awkward. We need to generate get_errno() and set_errno() diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index d6d7c70a8e..6c6ce0dab7 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -211,6 +211,9 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert) SYSCALL_LOOKUP(poll, 3, STUB_poll) SYSCALL_LOOKUP(select, 5, STUB_select) # endif +# ifndef CONFIG_SERIAL_TERMIOS + SYSCALL_LOOKUP(tcdrain, 1, STUB_tcdrain) +# endif #endif /* Board support */ diff --git a/syscall/syscall_stublookup.c b/syscall/syscall_stublookup.c index 5cdda6e17d..d58ae5c103 100644 --- a/syscall/syscall_stublookup.c +++ b/syscall/syscall_stublookup.c @@ -210,6 +210,8 @@ uintptr_t STUB_aio_write(int nbr, uintptr_t parm1); uintptr_t STUB_aio_fsync(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_aio_cancel(int nbr, uintptr_t parm1, uintptr_t parm2); +uintptr_t STUB_tcdrain(int nbr, uintptr_t parm1); + /* Board support */ uintptr_t STUB_boardctl(int nbr, uintptr_t parm1, uintptr_t parm2);