From 8dc15b11a00791cfcd4db7bcad989ddaf64523b8 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.oliveiramaroneze@cea.fr> Date: Fri, 9 Aug 2019 16:10:53 +0200 Subject: [PATCH] [Libc] fix several specifications --- share/libc/sys/resource.h | 26 ++++++++++++++++---------- share/libc/sys/time.h | 19 ++++++++++++++----- share/libc/time.h | 15 +++++++++++---- share/libc/unistd.h | 2 ++ tests/libc/unistd_h.c | 13 +++++++++++++ 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/share/libc/sys/resource.h b/share/libc/sys/resource.h index 566a0fa31e8..bcb311cb376 100644 --- a/share/libc/sys/resource.h +++ b/share/libc/sys/resource.h @@ -65,21 +65,27 @@ extern int getpriority(int which, id_t who); /*@ assigns \result \from which,who,prio; */ extern int setpriority(int which, id_t who, int prio); -/*@ assigns \result \from r; - @ assigns rl->rlim_cur \from r; - @ assigns rl->rlim_max \from r; +/*@ + requires valid_rlp: \valid(rlp); + assigns \result, *rlp \from resource; */ -extern int getrlimit(int r, struct rlimit *rl); +extern int getrlimit(int resource, struct rlimit *rlp); -/*@ assigns \result \from r; - @ assigns ru->ru_utime \from r; - @ assigns ru->ru_stime \from r; +/*@ + requires valid_r_usage: \valid(r_usage); + assigns *r_usage \from who; + assigns \result \from indirect:who; + ensures result_ok_or_error: \result == 0 || \result == -1; */ -extern int getrusage(int r, struct rusage *ru); +extern int getrusage(int who, struct rusage *r_usage); -/*@ assigns \result \from r,rl->rlim_cur,rl->rlim_max; +/*@ + requires valid_rlp: \valid_read(rlp); + assigns *rlp \from resource; + assigns \result \from indirect:resource, indirect:*rlp; + ensures result_ok_or_error: \result == 0 || \result == -1; */ -extern int setrlimit(int r, const struct rlimit * rl); +extern int setrlimit(int resource, const struct rlimit *rlp); __END_DECLS __POP_FC_STDLIB diff --git a/share/libc/sys/time.h b/share/libc/sys/time.h index 426f6376887..15213f4cbb1 100644 --- a/share/libc/sys/time.h +++ b/share/libc/sys/time.h @@ -30,6 +30,7 @@ __BEGIN_DECLS #include "../__fc_define_suseconds_t.h" #include "../__fc_define_fd_set_t.h" #include "../__fc_define_timespec.h" +#include "../__fc_string_axiomatic.h" struct timeval { time_t tv_sec; suseconds_t tv_usec; @@ -44,7 +45,11 @@ struct timezone { //@ ghost volatile unsigned int __fc_time __attribute__((FRAMA_C_MODEL)); //@ ghost extern int __fc_tz __attribute__((FRAMA_C_MODEL)); -/*@ assigns \result \from path[0..],times[0..1]; */ +/*@ + requires valid_path: valid_read_string(path); + requires valid_times: \valid_read(times+(0..1)); + assigns \result \from indirect:path[0..strlen(path)], indirect:times[0..1]; +*/ extern int utimes(const char *path, const struct timeval times[2]); /*@ assigns tv->tv_sec, tv->tv_usec \from __fc_time; @@ -83,10 +88,14 @@ extern int utimes(const char *path, const struct timeval times[2]); @*/ extern int gettimeofday(struct timeval * restrict tv, void * restrict tz); -/*@ assigns \result,__fc_time,__fc_tz - @ \from tv->tv_sec, tv->tv_usec, - @ tz->tz_dsttime, tz->tz_minuteswest; - @*/ +/*@ + requires valid_tv_or_null: \valid_read(tv) || tv == \null; + requires valid_tz_or_null: \valid_read(tz) || tz == \null; + assigns __fc_time, __fc_tz \from tv->tv_sec, tv->tv_usec, + tz->tz_dsttime, tz->tz_minuteswest; + assigns \result \from indirect:*tv, indirect:*tz; + ensures result_ok_or_error: \result == 0 || \result == -1; +*/ extern int settimeofday(const struct timeval *tv, const struct timezone *tz); #if (defined _POSIX_C_SOURCE && (_POSIX_C_SOURCE) >= 200112L) || \ diff --git a/share/libc/time.h b/share/libc/time.h index 52c66700cc8..f0de06cabd8 100644 --- a/share/libc/time.h +++ b/share/libc/time.h @@ -86,7 +86,11 @@ extern clock_t clock(void); /*@ assigns \result \from time1, time0; */ extern double difftime(time_t time1, time_t time0); -/*@ assigns *timeptr, \result \from *timeptr; */ +/*@ + requires valid_timeptr: \valid(timeptr); + assigns *timeptr \from *timeptr; + assigns \result \from indirect:*timeptr; + */ extern time_t mktime(struct tm *timeptr); /*@ @@ -122,14 +126,18 @@ extern char *ctime(const time_t *timer); struct tm __fc_time_tm; struct tm * const __fc_p_time_tm = &__fc_time_tm; -/*@ assigns \result \from __fc_p_time_tm; +/*@ + requires valid_timer: \valid_read(timer); + assigns \result \from __fc_p_time_tm; assigns __fc_time_tm \from *timer; ensures result_null_or_internal_tm: \result == &__fc_time_tm || \result == \null ; */ extern struct tm *gmtime(const time_t *timer); -/*@ assigns \result \from __fc_p_time_tm; +/*@ + requires valid_timer: \valid_read(timer); + assigns \result \from __fc_p_time_tm; assigns __fc_time_tm \from *timer; ensures result_null_or_internal_tm: \result == &__fc_time_tm || \result == \null; @@ -290,7 +298,6 @@ extern int timer_getoverrun(timer_t); extern int timer_gettime(timer_t, struct itimerspec *); extern int timer_settime(timer_t, int, const struct itimerspec *restrict, struct itimerspec *restrict); -extern void tzset(void); extern int daylight; extern long timezone; diff --git a/share/libc/unistd.h b/share/libc/unistd.h index 4a8a0455ceb..799cb03c7bd 100644 --- a/share/libc/unistd.h +++ b/share/libc/unistd.h @@ -985,6 +985,7 @@ extern long pathconf(char const *path, int name); extern int pause(void); /*@ + requires valid_pipefd: \valid(pipefd+(0..1)); assigns pipefd[0..1] \from indirect:__fc_fds[0..]; assigns \result \from indirect:__fc_fds[0..]; ensures initialization:pipefd: \initialized(&pipefd[0..1]); @@ -1100,6 +1101,7 @@ volatile char *__fc_p_ttyname = __fc_ttyname; /*@ // missing: may assign to errno: EBADF, ENOTTY + requires valid_fildes: 0 <= fildes < __FC_MAX_OPEN_FILES; assigns \result \from __fc_p_ttyname, indirect:fildes; ensures result_name_or_null: \result == __fc_p_ttyname || \result == \null; */ diff --git a/tests/libc/unistd_h.c b/tests/libc/unistd_h.c index b625b3b83d2..8c3104215bf 100644 --- a/tests/libc/unistd_h.c +++ b/tests/libc/unistd_h.c @@ -91,5 +91,18 @@ int main() { r = chroot("/tmp"); + if (nondet) { + pipe(0); // invalid fildes + //@ assert unreachable:\false; + } + int halfpipe; + if (nondet) { + pipe(&halfpipe); // invalid fildes + //@ assert unreachable:\false; + } + int pipefd[2]; + r = pipe(pipefd); + //@ check ok: r == 0 || r == -1; + return 0; } -- GitLab