From c348b51275d56861001237df23d5a35b8b3e505a Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Wed, 13 Nov 2019 15:20:09 +0100 Subject: [PATCH] [Libc] add specs in termios.h --- share/libc/termios.h | 48 +++++++++++++-- tests/libc/oracle/fc_libc.0.res.oracle | 85 +++++++++++++------------- tests/libc/oracle/fc_libc.1.res.oracle | 42 +++++++++++++ tests/libc/termios.c | 8 +++ 4 files changed, 136 insertions(+), 47 deletions(-) diff --git a/share/libc/termios.h b/share/libc/termios.h index d53d69c2c61..ccaba4b7898 100644 --- a/share/libc/termios.h +++ b/share/libc/termios.h @@ -170,13 +170,51 @@ struct termios { cc_t c_cc[NCCS]; /* special characters */ }; -extern speed_t cfgetispeed(const struct termios *); -extern speed_t cfgetospeed(const struct termios *); -extern int cfsetispeed(struct termios *, speed_t); -extern int cfsetospeed(struct termios *, speed_t); +/*@ + requires valid_termios_p: \valid_read(termios_p); + assigns \result \from indirect:termios_p, *termios_p; + // missing ensures result_is_valid_speed: speed \in {valid baud rates}; +*/ +extern speed_t cfgetispeed(const struct termios *termios_p); + +/*@ + requires valid_termios_p: \valid_read(termios_p); + assigns \result \from indirect:termios_p, *termios_p; + // missing ensures result_is_valid_speed: speed \in {valid baud rates}; +*/ +extern speed_t cfgetospeed(const struct termios *termios_p); + +/*@ + // missing requires valid_speed: speed \in {valid baud rates}; + requires valid_termios_p: \valid(termios_p); + assigns \result, *termios_p \from indirect:termios_p, speed; + ensures result_ok_or_error: \result == 0 || \result == -1; + */ +extern int cfsetispeed(struct termios *termios_p, speed_t speed); + +/*@ + // missing requires valid_speed: speed \in {valid baud rates}; + requires valid_termios_p: \valid(termios_p); + assigns \result, *termios_p \from indirect:termios_p, speed; + ensures result_ok_or_error: \result == 0 || \result == -1; + */ +extern int cfsetospeed(struct termios *termios_p, speed_t speed); + extern int tcdrain(int); extern int tcflow(int, int); -extern int tcflush(int, int); + +/*@ + // missing requires valid_fd: {fd is an open file descriptor + // associated with a terminal}; + requires valid_queue_selector: queue_selector == TCIFLUSH + || queue_selector == TCOFLUSH + || queue_selector == TCIOFLUSH; + assigns \result \from indirect:fd, indirect:queue_selector, + indirect:Frama_C_entropy_source; + assigns Frama_C_entropy_source \from Frama_C_entropy_source; + ensures result_ok_or_error: \result == 0 || \result == -1; + */ +extern int tcflush(int fd, int queue_selector); /*@ requires valid_termios_p: \valid(termios_p); assigns \result, *termios_p \from indirect:fd, diff --git a/tests/libc/oracle/fc_libc.0.res.oracle b/tests/libc/oracle/fc_libc.0.res.oracle index d64b91d8754..4576d6a15ca 100644 --- a/tests/libc/oracle/fc_libc.0.res.oracle +++ b/tests/libc/oracle/fc_libc.0.res.oracle @@ -40,7 +40,7 @@ unsetenv (0 call); wcscat (0 call); wcscpy (0 call); wcslen (2 calls); wcsncat (0 call); wcsncpy (0 call); wmemcpy (0 call); wmemset (0 call); - Undefined functions (385) + Undefined functions (390) ========================= FD_CLR (0 call); FD_ISSET (0 call); FD_SET (0 call); FD_ZERO (0 call); Frama_C_int_interval (0 call); Frama_C_long_interval (0 call); @@ -74,35 +74,36 @@ atanl (0 call); atexit (0 call); atof (0 call); atol (0 call); atoll (0 call); basename (0 call); bind (0 call); bsearch (0 call); bzero (0 call); ceil (0 call); ceilf (0 call); ceill (0 call); - chdir (0 call); chown (0 call); chroot (0 call); clearerr (0 call); - clearerr_unlocked (0 call); clock (0 call); clock_gettime (0 call); - clock_nanosleep (0 call); close (0 call); closedir (0 call); - closelog (0 call); connect (0 call); cos (0 call); cosf (0 call); - cosl (0 call); creat (0 call); ctime (0 call); difftime (0 call); - dirname (0 call); div (0 call); drand48 (0 call); dup (0 call); - dup2 (0 call); erand48 (0 call); execl (0 call); execle (0 call); - execlp (0 call); execv (0 call); execve (0 call); execvp (0 call); - exit (0 call); exp (0 call); expf (0 call); fabsl (0 call); fclose (0 call); - fcntl (0 call); fdopen (0 call); feof (2 calls); feof_unlocked (0 call); - ferror (2 calls); ferror_unlocked (0 call); fflush (0 call); fgetc (1 call); - fgetpos (0 call); fgets (0 call); fgetws (0 call); fileno (0 call); - fileno_unlocked (0 call); flock (0 call); flockfile (0 call); - floor (0 call); floorf (0 call); floorl (0 call); fmod (0 call); - fmodf (0 call); fopen (0 call); fork (0 call); fputc (0 call); - fputs (0 call); fread (0 call); free (1 call); freeaddrinfo (0 call); - freopen (0 call); fseek (0 call); fsetpos (0 call); ftell (0 call); - ftrylockfile (0 call); funlockfile (0 call); fwrite (0 call); - gai_strerror (0 call); getc (0 call); getc_unlocked (0 call); - getchar (0 call); getchar_unlocked (0 call); getcwd (0 call); - getegid (0 call); geteuid (0 call); getgid (0 call); gethostname (0 call); - getitimer (0 call); getopt (0 call); getopt_long (0 call); - getopt_long_only (0 call); getpgid (0 call); getpgrp (0 call); - getpid (0 call); getppid (0 call); getpriority (0 call); getpwnam (0 call); - getpwuid (0 call); getresgid (0 call); getresuid (0 call); - getrlimit (0 call); getrusage (0 call); gets (0 call); getsid (0 call); - getsockname (0 call); getsockopt (0 call); gettimeofday (0 call); - getuid (0 call); gmtime (0 call); htonl (0 call); htons (0 call); - iconv (0 call); iconv_close (0 call); iconv_open (0 call); + cfgetispeed (0 call); cfgetospeed (0 call); cfsetispeed (0 call); + cfsetospeed (0 call); chdir (0 call); chown (0 call); chroot (0 call); + clearerr (0 call); clearerr_unlocked (0 call); clock (0 call); + clock_gettime (0 call); clock_nanosleep (0 call); close (0 call); + closedir (0 call); closelog (0 call); connect (0 call); cos (0 call); + cosf (0 call); cosl (0 call); creat (0 call); ctime (0 call); + difftime (0 call); dirname (0 call); div (0 call); drand48 (0 call); + dup (0 call); dup2 (0 call); erand48 (0 call); execl (0 call); + execle (0 call); execlp (0 call); execv (0 call); execve (0 call); + execvp (0 call); exit (0 call); exp (0 call); expf (0 call); fabsl (0 call); + fclose (0 call); fcntl (0 call); fdopen (0 call); feof (2 calls); + feof_unlocked (0 call); ferror (2 calls); ferror_unlocked (0 call); + fflush (0 call); fgetc (1 call); fgetpos (0 call); fgets (0 call); + fgetws (0 call); fileno (0 call); fileno_unlocked (0 call); flock (0 call); + flockfile (0 call); floor (0 call); floorf (0 call); floorl (0 call); + fmod (0 call); fmodf (0 call); fopen (0 call); fork (0 call); + fputc (0 call); fputs (0 call); fread (0 call); free (1 call); + freeaddrinfo (0 call); freopen (0 call); fseek (0 call); fsetpos (0 call); + ftell (0 call); ftrylockfile (0 call); funlockfile (0 call); + fwrite (0 call); gai_strerror (0 call); getc (0 call); + getc_unlocked (0 call); getchar (0 call); getchar_unlocked (0 call); + getcwd (0 call); getegid (0 call); geteuid (0 call); getgid (0 call); + gethostname (0 call); getitimer (0 call); getopt (0 call); + getopt_long (0 call); getopt_long_only (0 call); getpgid (0 call); + getpgrp (0 call); getpid (0 call); getppid (0 call); getpriority (0 call); + getpwnam (0 call); getpwuid (0 call); getresgid (0 call); + getresuid (0 call); getrlimit (0 call); getrusage (0 call); gets (0 call); + getsid (0 call); getsockname (0 call); getsockopt (0 call); + gettimeofday (0 call); getuid (0 call); gmtime (0 call); htonl (0 call); + htons (0 call); iconv (0 call); iconv_close (0 call); iconv_open (0 call); inet_addr (2 calls); inet_ntoa (0 call); inet_ntop (0 call); inet_pton (0 call); isascii (0 call); isatty (0 call); jrand48 (0 call); kill (0 call); killpg (0 call); labs (0 call); lcong48 (0 call); @@ -146,17 +147,17 @@ strtoimax (0 call); strtok (0 call); strtok_r (0 call); strtol (0 call); strtold (0 call); strtoll (0 call); strtoul (0 call); strtoull (0 call); strxfrm (0 call); sync (0 call); sysconf (0 call); syslog (0 call); - system (0 call); tcgetattr (0 call); tcsetattr (0 call); time (0 call); - times (0 call); tmpfile (0 call); tmpnam (0 call); trunc (0 call); - truncf (0 call); truncl (0 call); ttyname (0 call); tzset (0 call); - umask (0 call); ungetc (0 call); unlink (0 call); usleep (0 call); - utimes (0 call); vfprintf (0 call); vfscanf (0 call); vprintf (0 call); - vscanf (0 call); vsnprintf (0 call); vsprintf (0 call); vsyslog (0 call); - wait (0 call); waitpid (0 call); wcschr (0 call); wcscmp (0 call); - wcscspn (0 call); wcslcat (0 call); wcslcpy (0 call); wcsncmp (0 call); - wcspbrk (0 call); wcsrchr (0 call); wcsspn (0 call); wcsstr (0 call); - wcstombs (0 call); wctomb (0 call); wmemchr (0 call); wmemcmp (0 call); - wmemmove (0 call); write (0 call); + system (0 call); tcflush (0 call); tcgetattr (0 call); tcsetattr (0 call); + time (0 call); times (0 call); tmpfile (0 call); tmpnam (0 call); + trunc (0 call); truncf (0 call); truncl (0 call); ttyname (0 call); + tzset (0 call); umask (0 call); ungetc (0 call); unlink (0 call); + usleep (0 call); utimes (0 call); vfprintf (0 call); vfscanf (0 call); + vprintf (0 call); vscanf (0 call); vsnprintf (0 call); vsprintf (0 call); + vsyslog (0 call); wait (0 call); waitpid (0 call); wcschr (0 call); + wcscmp (0 call); wcscspn (0 call); wcslcat (0 call); wcslcpy (0 call); + wcsncmp (0 call); wcspbrk (0 call); wcsrchr (0 call); wcsspn (0 call); + wcsstr (0 call); wcstombs (0 call); wctomb (0 call); wmemchr (0 call); + wmemcmp (0 call); wmemmove (0 call); write (0 call); 'Extern' global variables (16) ============================== @@ -179,7 +180,7 @@ Goto = 89 Assignment = 438 Exit point = 82 - Function = 467 + Function = 472 Function call = 89 Pointer dereferencing = 158 Cyclomatic complexity = 286 diff --git a/tests/libc/oracle/fc_libc.1.res.oracle b/tests/libc/oracle/fc_libc.1.res.oracle index 82cff401f47..26025f53b3f 100644 --- a/tests/libc/oracle/fc_libc.1.res.oracle +++ b/tests/libc/oracle/fc_libc.1.res.oracle @@ -365,6 +365,7 @@ struct tms { }; typedef unsigned int tcflag_t; typedef unsigned char cc_t; +typedef unsigned int speed_t; struct termios { tcflag_t c_iflag ; tcflag_t c_oflag ; @@ -7935,6 +7936,47 @@ extern pid_t wait(int *stat_loc); */ extern pid_t waitpid(pid_t pid, int *stat_loc, int options); +/*@ requires valid_termios_p: \valid_read(termios_p); + assigns \result; + assigns \result \from (indirect: termios_p), *termios_p; + */ +extern speed_t cfgetispeed(struct termios const *termios_p); + +/*@ requires valid_termios_p: \valid_read(termios_p); + assigns \result; + assigns \result \from (indirect: termios_p), *termios_p; + */ +extern speed_t cfgetospeed(struct termios const *termios_p); + +/*@ requires valid_termios_p: \valid(termios_p); + ensures result_ok_or_error: \result â‰، 0 ∨ \result â‰، -1; + assigns \result, *termios_p; + assigns \result \from (indirect: termios_p), speed; + assigns *termios_p \from (indirect: termios_p), speed; + */ +extern int cfsetispeed(struct termios *termios_p, speed_t speed); + +/*@ requires valid_termios_p: \valid(termios_p); + ensures result_ok_or_error: \result â‰، 0 ∨ \result â‰، -1; + assigns \result, *termios_p; + assigns \result \from (indirect: termios_p), speed; + assigns *termios_p \from (indirect: termios_p), speed; + */ +extern int cfsetospeed(struct termios *termios_p, speed_t speed); + +/*@ requires + valid_queue_selector: + queue_selector â‰، 0 ∨ queue_selector â‰، 1 ∨ + queue_selector â‰، 2; + ensures result_ok_or_error: \result â‰، 0 ∨ \result â‰، -1; + assigns \result, Frama_C_entropy_source; + assigns \result + \from (indirect: fd), (indirect: queue_selector), + (indirect: Frama_C_entropy_source); + assigns Frama_C_entropy_source \from Frama_C_entropy_source; + */ +extern int tcflush(int fd, int queue_selector); + /*@ requires valid_termios_p: \valid(termios_p); assigns \result, *termios_p, Frama_C_entropy_source; assigns \result \from (indirect: fd), (indirect: Frama_C_entropy_source); diff --git a/tests/libc/termios.c b/tests/libc/termios.c index 9f3928b7f8f..6ba105607a2 100644 --- a/tests/libc/termios.c +++ b/tests/libc/termios.c @@ -15,5 +15,13 @@ int main() { } tio.c_lflag = (ECHO|ICANON|ISIG|ECHOE|ECHOK|ECHONL); tio.c_oflag = OPOST; + + res = cfsetispeed(&tio, B9600); + if (res) return 1; + res = cfsetospeed(&tio, B50); + if (res) return 1; + speed_t sp1 = cfgetispeed(&tio); + speed_t sp2 = cfgetospeed(&tio); + res = tcflush(fd, TCIOFLUSH); return tcsetattr(fd, TCSADRAIN, &tio); } -- GitLab