diff --git a/tests/libc/oracle/fc_libc.0.res.oracle b/tests/libc/oracle/fc_libc.0.res.oracle index 64302fc49a200a36a4598d1a0179f3b0f3eda298..9e316f61b4335404e6ac699dd0301e26bf4c48d7 100644 --- a/tests/libc/oracle/fc_libc.0.res.oracle +++ b/tests/libc/oracle/fc_libc.0.res.oracle @@ -36,7 +36,6 @@ #include "fcntl.h" #include "fenv.c" #include "fenv.h" -#include "getopt.c" #include "getopt.h" #include "glob.c" #include "glob.h" @@ -75,6 +74,7 @@ #include "sys/resource.h" #include "sys/select.h" #include "sys/sendfile.h" +#include "sys/socket.c" #include "sys/socket.h" #include "sys/stat.h" #include "sys/time.h" diff --git a/tests/libc/oracle/fc_libc.1.res.oracle b/tests/libc/oracle/fc_libc.1.res.oracle index 987c07f9c09f869b07eef105c2fac5aee3626783..b55c780a65a36fcbfea04b1d791765a50c5eec71 100644 --- a/tests/libc/oracle/fc_libc.1.res.oracle +++ b/tests/libc/oracle/fc_libc.1.res.oracle @@ -36,17 +36,6 @@ struct __fc_fenv_t { unsigned short __unused5 ; }; typedef struct __fc_fenv_t fenv_t; -typedef unsigned int gid_t; -typedef unsigned int uid_t; -typedef long off_t; -typedef int pid_t; -typedef unsigned int useconds_t; -struct option { - char const *name ; - int has_arg ; - int *flag ; - int val ; -}; struct __fc_glob_t { unsigned int gl_pathc ; char **gl_pathv ; @@ -127,6 +116,9 @@ struct __fc_pthread_t { int _fc ; }; typedef struct __fc_pthread_t pthread_t; +typedef int pid_t; +typedef unsigned int gid_t; +typedef unsigned int uid_t; typedef unsigned long sigset_t; union sigval { int sival_int ; @@ -251,6 +243,7 @@ typedef unsigned int blksize_t; typedef unsigned int dev_t; typedef unsigned int mode_t; typedef unsigned int nlink_t; +typedef long off_t; struct stat { dev_t st_dev ; ino_t st_ino ; @@ -313,6 +306,7 @@ typedef unsigned long long atomic_ullong; typedef void * const * va_list; typedef unsigned int id_t; typedef int suseconds_t; +typedef unsigned int useconds_t; struct dirent { ino_t d_ino ; off_t d_off ; @@ -342,6 +336,12 @@ struct flock { off_t l_len ; pid_t l_pid ; }; +struct option { + char const *name ; + int has_arg ; + int *flag ; + int val ; +}; typedef void * iconv_t; struct pollfd { int fd ; @@ -405,14 +405,22 @@ int volatile Frama_C_entropy_source __attribute__((__unused__)); __attribute__((__FC_BUILTIN__)) int Frama_C_nondet(int a, int b); + __attribute__((__FC_BUILTIN__)) void *Frama_C_nondet_ptr(void *a, void *b); + __attribute__((__FC_BUILTIN__)) int Frama_C_interval(int min, int max); + __attribute__((__FC_BUILTIN__)) unsigned char Frama_C_unsigned_char_interval +(unsigned char min, unsigned char max); + __attribute__((__FC_BUILTIN__)) char Frama_C_char_interval(char min, char max); __attribute__((__FC_BUILTIN__)) unsigned int Frama_C_unsigned_int_interval (unsigned int min, unsigned int max); + __attribute__((__FC_BUILTIN__)) long Frama_C_long_interval(long min, + long max); + __attribute__((__noreturn__, __FC_BUILTIN__)) void Frama_C_abort(void); unsigned int volatile __fc_unsigned_int_entropy; @@ -461,6 +469,20 @@ int Frama_C_nondet(int a, int b) return tmp; } +/*@ ensures result_a_or_b: \result ≡ \old(a) ∨ \result ≡ \old(b); + assigns \result, Frama_C_entropy_source; + assigns \result \from a, b, Frama_C_entropy_source; + assigns Frama_C_entropy_source \from Frama_C_entropy_source; + */ + __attribute__((__FC_BUILTIN__)) void *Frama_C_nondet_ptr(void *a, void *b); +void *Frama_C_nondet_ptr(void *a, void *b) +{ + void *tmp; + Frama_C_update_entropy(); + if (Frama_C_entropy_source) tmp = a; else tmp = b; + return tmp; +} + /*@ requires order: min ≤ max; ensures result_bounded: \old(min) ≤ \result ≤ \old(max); assigns \result, Frama_C_entropy_source; @@ -497,6 +519,24 @@ char Frama_C_char_interval(char min, char max) return __retres; } +/*@ requires order: min ≤ max; + ensures result_bounded: \old(min) ≤ \result ≤ \old(max); + assigns \result, Frama_C_entropy_source; + assigns \result \from min, max, Frama_C_entropy_source; + assigns Frama_C_entropy_source \from Frama_C_entropy_source; + */ + __attribute__((__FC_BUILTIN__)) unsigned char Frama_C_unsigned_char_interval +(unsigned char min, unsigned char max); +unsigned char Frama_C_unsigned_char_interval(unsigned char min, + unsigned char max) +{ + unsigned char __retres; + int tmp; + tmp = Frama_C_interval((int)min,(int)max); + __retres = (unsigned char)tmp; + return __retres; +} + /*@ requires order: min ≤ max; ensures result_bounded: \old(min) ≤ \result ≤ \old(max); assigns \result, Frama_C_entropy_source; @@ -517,6 +557,26 @@ unsigned int Frama_C_unsigned_int_interval(unsigned int min, unsigned int max) return r; } +/*@ requires order: min ≤ max; + ensures result_bounded: \old(min) ≤ \result ≤ \old(max); + assigns \result, Frama_C_entropy_source; + assigns \result \from min, max, Frama_C_entropy_source; + assigns Frama_C_entropy_source \from Frama_C_entropy_source; + */ + __attribute__((__FC_BUILTIN__)) long Frama_C_long_interval(long min, + long max); +long Frama_C_long_interval(long min, long max) +{ + long r; + long aux; + Frama_C_update_entropy(); + aux = __fc_long_entropy; + if (aux >= min) + if (aux <= max) r = aux; else r = min; + else r = min; + return r; +} + extern __attribute__((__noreturn__)) void __builtin_abort(void); /*@ terminates \false; @@ -2798,3762 +2858,3833 @@ int fesetenv(fenv_t const *envp) return __retres; } -extern int volatile __fc_fds[1024]; +int glob(char const *pattern, int flags, + int (*errfunc)(char const *epath, int eerrno), glob_t *pglob); -/*@ requires valid_string_path: valid_read_string(path); - requires valid_amode: (amode & ~((4 | 2) | 1)) ≡ 0 ∨ amode ≡ 0; - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result - \from (indirect: path), (indirect: *(path + (0 ..))), (indirect: amode); - */ -extern int access(char const *path, int amode); +void globfree(glob_t *pglob); -/*@ requires valid_string_path: valid_read_string(path); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result \from (indirect: path), (indirect: *(path + (0 ..))); - */ -extern int chdir(char const *path); +int glob(char const *pattern, int flags, + int (*errfunc)(char const *epath, int eerrno), glob_t *pglob) +{ + int __retres; + int tmp; + unsigned int tmp_0; + char **tmp_1; + int tmp_4; + tmp = Frama_C_interval(0,10); + pglob->gl_pathc = (unsigned int)tmp; + if (flags & (1 << 3)) tmp_0 = pglob->gl_offs; else tmp_0 = (unsigned int)0; + size_t reserve_offs = tmp_0; + size_t prev_len = (size_t)0; + if (flags & (1 << 5)) + while (*(pglob->gl_pathv + (reserve_offs + prev_len))) prev_len ++; + if (flags & (1 << 5)) tmp_1 = pglob->gl_pathv; else tmp_1 = (char **)0; + char **path = tmp_1; + if (pglob->gl_pathc == (unsigned int)0) + if (flags & (1 << 4)) { + pglob->gl_pathv = (char **)realloc((void *)path, + ((reserve_offs + prev_len) + (size_t)2) * sizeof(char *)); + if (! pglob->gl_pathv) { + __retres = 1; + goto return_label; + } + { + size_t i = (size_t)0; + while (i < reserve_offs) { + *(pglob->gl_pathv + i) = (char *)0; + i ++; + } + } + *(pglob->gl_pathv + (reserve_offs + prev_len)) = (char *)pattern; + *(pglob->gl_pathv + ((reserve_offs + prev_len) + (size_t)1)) = (char *)0; + __retres = 0; + goto return_label; + } + else { + __retres = 3; + goto return_label; + } + pglob->gl_pathv = (char **)realloc((void *)path, + (((reserve_offs + prev_len) + pglob->gl_pathc) + (size_t)1) * sizeof(char *)); + if (! pglob->gl_pathv) { + __retres = 1; + goto return_label; + } + { + size_t i_0 = (size_t)0; + while (i_0 < reserve_offs) { + *(pglob->gl_pathv + i_0) = (char *)0; + i_0 ++; + } + } + { + size_t i_1 = (size_t)0; + while (i_1 < pglob->gl_pathc) { + *(pglob->gl_pathv + ((reserve_offs + prev_len) + i_1)) = (char *)"glob result"; + i_1 ++; + } + } + *(pglob->gl_pathv + ((prev_len + reserve_offs) + pglob->gl_pathc)) = (char *)0; + tmp_4 = Frama_C_nondet(0,1); + if (tmp_4) { + __retres = 0; + goto return_label; + } + else { + if (errfunc) { + int tmp_3; + int tmp_2; + tmp_2 = Frama_C_interval(0,255); + tmp_3 = (*errfunc)("glob.c error path",tmp_2); + int res = tmp_3; + if (res) { + __retres = 2; + goto return_label; + } + else + if (flags & (1 << 0)) { + __retres = 2; + goto return_label; + } + } + __retres = 0; + goto return_label; + } + return_label: return __retres; +} -/*@ requires valid_string_path: valid_read_string(path); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result \from (indirect: path), (indirect: *(path + (0 ..))); - */ -extern int chroot(char const *path); +void globfree(glob_t *pglob) +{ + if (pglob->gl_pathc > (unsigned int)0) free((void *)pglob->gl_pathv); + return; +} -/*@ requires valid_string_path: valid_read_string(path); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result - \from (indirect: path), (indirect: *(path + (0 ..))), - (indirect: owner), (indirect: group); - */ -extern int chown(char const *path, uid_t owner, gid_t group); +intmax_t imaxabs(intmax_t c); -/*@ requires valid_fd: 0 ≤ fd < 1024; - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns __fc_fds[fd], \result; - assigns __fc_fds[fd] \from fd, __fc_fds[fd]; - assigns \result \from (indirect: fd), (indirect: __fc_fds[fd]); - */ -extern int close(int fd); +imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); -/*@ requires valid_fildes: 0 ≤ fildes < 1024; - ensures - result_valid_fildes_or_error: - \result ≡ -1 ∨ (\old(fildes) ≤ \result < 1024); - assigns __fc_fds[fildes ..], \result; - assigns __fc_fds[fildes ..] \from fildes; - assigns \result \from fildes; +/*@ assigns \result, *(endptr + (..)), __fc_errno; + assigns \result \from *(nptr + (..)), base; + assigns *(endptr + (..)) \from *(nptr + (..)), base; + assigns __fc_errno \from *(nptr + (..)), base; */ -extern int dup(int fildes); +extern intmax_t strtoimax(char const * restrict nptr, + char ** restrict endptr, int base); -/*@ requires valid_fildes: 0 ≤ fildes < 1024; - requires valid_fildes2: 0 ≤ fildes2 < 1024; +/*@ requires abs_representable: c > -9223372036854775807LL - 1LL; + ensures positive_result: \result ≥ 0.; ensures - result_fildes2_or_error: \result ≡ \old(fildes2) ∨ \result ≡ -1; - assigns __fc_fds[fildes2], \result; - assigns __fc_fds[fildes2] \from fildes, fildes2, __fc_fds[fildes2]; - assigns \result - \from fildes, fildes2, __fc_fds[fildes], __fc_fds[fildes2]; - */ -extern int dup2(int fildes, int fildes2); - -/*@ requires valid_string_path: valid_read_string(path); - requires valid_string_arg: valid_read_string(arg); + equal_magnitude_result: \result ≡ \old(c) ∨ \result ≡ -\old(c); + ensures logical_abs_result: \result ≡ \abs(\old(c)); assigns \result; - assigns \result \from *(path + (0 ..)), *(arg + (0 ..)); + assigns \result \from c; */ -extern int execl(char const *path, char const *arg, void * const *__va_params); +intmax_t imaxabs(intmax_t c) +{ + intmax_t __retres; + if (c > (intmax_t)0) { + __retres = c; + goto return_label; + } + else { + __retres = - c; + goto return_label; + } + return_label: return __retres; +} -/*@ requires valid_string_path: valid_read_string(path); - requires valid_string_arg: valid_read_string(arg); +/*@ requires no_div_by_zero: denom ≢ 0; + requires no_overflow: denom ≢ -1 ∨ (intmax_t)(-numer) ≢ numer; + ensures correct_div: \result.quot ≡ \old(numer) / \old(denom); + ensures correct_mod: \result.rem ≡ \old(numer) % \old(denom); assigns \result; - assigns \result \from *(path + (0 ..)), *(arg + (0 ..)); + assigns \result \from numer, denom; */ -extern int execle(char const *path, char const *arg, - void * const *__va_params); - -/*@ requires valid_string_path: valid_read_string(path); - requires valid_string_arg: valid_read_string(arg); - assigns \result; - assigns \result \from *(path + (0 ..)), *(arg + (0 ..)); +imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t r; + r.quot = numer / denom; + r.rem = numer % denom; + return r; +} + +extern struct lconv *__fc_locale; + +extern char *__fc_locale_names[512]; + +char *setlocale(int category, char const *locale); + +struct lconv *localeconv(void); + +struct lconv __C_locale = + {.decimal_point = (char *)".", + .thousands_sep = (char *)"", + .grouping = (char *)"", + .int_curr_symbol = (char *)"", + .currency_symbol = (char *)"", + .mon_decimal_point = (char *)"", + .mon_thousands_sep = (char *)"", + .mon_grouping = (char *)"", + .positive_sign = (char *)"", + .negative_sign = (char *)"", + .int_frac_digits = (char)127, + .frac_digits = (char)127, + .p_cs_precedes = (char)127, + .p_sep_by_space = (char)127, + .n_cs_precedes = (char)127, + .n_sep_by_space = (char)127, + .p_sign_posn = (char)127, + .n_sign_posn = (char)127, + .int_p_cs_precedes = (char)127, + .int_p_sep_by_space = (char)127, + .int_n_cs_precedes = (char)127, + .int_n_sep_by_space = (char)127, + .int_p_sign_posn = (char)127, + .int_n_sign_posn = (char)127}; +struct lconv *__frama_c_locale = & __C_locale; +char const *__frama_c_locale_names[512] = {"C"}; +/*@ requires + locale_null_or_valid_string: + locale ≡ \null ∨ valid_read_string(locale); + ensures + result_null_or_locale_name: + \result ≡ \null ∨ + (\valid(\result) ∧ (∃ ℤ i; \result ≡ __fc_locale_names[i])); + assigns __fc_locale, \result; + assigns __fc_locale \from category, *(locale + (..)); + assigns \result \from __fc_locale, category, *(locale + (..)); */ -extern int execlp(char const *path, char const *arg, - void * const *__va_params); +char *setlocale(int category, char const *locale) +{ + char *__retres; + if ((int)*locale == 'C') { + __frama_c_locale = & __C_locale; + __retres = (char *)__frama_c_locale_names[0]; + goto return_label; + } + __retres = (char *)0; + return_label: return __retres; +} -/*@ requires valid_string_path: valid_read_string(path); - requires valid_string_argv0: valid_read_string(*(argv + 0)); +/*@ ensures result_current_locale: \result ≡ __fc_locale; assigns \result; - assigns \result \from *(path + (0 ..)), *(argv + (0 ..)); + assigns \result \from __fc_locale; */ -extern int execv(char const *path, char * const *argv); +struct lconv *localeconv(void) +{ + return __frama_c_locale; +} -/*@ requires valid_path: valid_read_string(path); - requires valid_argv0: valid_read_string(*(argv + 0)); +/*@ assigns \result; + assigns \result \from x; + + behavior nan: + assumes is_nan: \is_NaN(x); + ensures fp_nan: \result ≡ 0; + + behavior inf: + assumes is_infinite: ¬\is_NaN(x) ∧ ¬\is_finite(x); + ensures fp_infinite: \result ≡ 1; + + behavior zero: + assumes is_a_zero: x ≡ 0.0; + ensures fp_zero: \result ≡ 2; + + behavior subnormal: + assumes is_finite: \is_finite(x); + assumes + is_subnormal: + (x > 0.0 ∧ x < 0x1p-126) ∨ (x < 0.0 ∧ x > -0x1p-126); + ensures fp_subnormal: \result ≡ 3; + + behavior normal: + assumes is_finite: \is_finite(x); + assumes not_subnormal: x ≤ -0x1p-126 ∨ x ≥ 0x1p-126; + ensures fp_normal: \result ≡ 4; + + complete behaviors normal, subnormal, zero, inf, nan; + disjoint behaviors normal, subnormal, zero, inf, nan; + */ +int __fc_fpclassifyf(float x); + +/*@ assigns \result; + assigns \result \from x; + + behavior nan: + assumes is_nan: \is_NaN(x); + ensures fp_nan: \result ≡ 0; + + behavior inf: + assumes is_infinite: ¬\is_NaN(x) ∧ ¬\is_finite(x); + ensures fp_infinite: \result ≡ 1; + + behavior zero: + assumes is_a_zero: x ≡ 0.0; + ensures fp_zero: \result ≡ 2; + + behavior subnormal: + assumes is_finite: \is_finite(x); + assumes + is_subnormal: + (x > 0.0 ∧ x < 0x1p-1022) ∨ (x < 0.0 ∧ x > -0x1p-1022); + ensures fp_subnormal: \result ≡ 3; + + behavior normal: + assumes is_finite: \is_finite(x); + assumes not_subnormal: x ≤ -0x1p-1022 ∨ x ≥ 0x1p-1022; + ensures fp_normal: \result ≡ 4; + + complete behaviors normal, subnormal, zero, inf, nan; + disjoint behaviors normal, subnormal, zero, inf, nan; + */ +int __fc_fpclassify(double x); + +/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; + ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from *(path + (0 ..)), *(argv + (0 ..)); + assigns \result \from x; */ -extern int execve(char const *path, char * const *argv, char * const *env); +extern double acos(double x); -/*@ requires valid_string_path: valid_read_string(path); - requires valid_string_argv0: valid_read_string(*(argv + 0)); +/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; + ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from *(path + (0 ..)), *(argv + (0 ..)); + assigns \result \from x; */ -extern int execvp(char const *path, char * const *argv); +extern float acosf(float x); -/*@ ensures never_terminates: \false; - assigns \nothing; */ -extern __attribute__((__noreturn__)) void _exit(int __x0); +/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; + ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + */ +extern long double acosl(long double x); -/*@ ensures - result_ok_child_or_error: - \result ≡ 0 ∨ \result > 0 ∨ \result ≡ -1; +/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from \nothing; + assigns \result \from x; */ -extern pid_t fork(void); +extern double asin(double x); -/*@ requires valid_buf: \valid(buf + (0 .. size - 1)); - ensures result_ok_or_error: \result ≡ \null ∨ \result ≡ \old(buf); - assigns *(buf + (0 .. size - 1)), \result; - assigns *(buf + (0 .. size - 1)) \from (indirect: buf), (indirect: size); - assigns \result \from buf, (indirect: size); +/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; */ -extern char *getcwd(char *buf, size_t size); +extern float asinf(float x); -/*@ assigns \result; - assigns \result \from \nothing; */ -extern gid_t getegid(void); +/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + */ +extern long double asinl(long double x); -/*@ assigns \result; - assigns \result \from \nothing; */ -extern uid_t geteuid(void); +/*@ requires number_arg: ¬\is_NaN(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1.571 ≤ \result ≤ 1.571; + assigns \result; + assigns \result \from x; + */ +extern float atanf(float x); -/*@ assigns \result; - assigns \result \from \nothing; */ -extern gid_t getgid(void); +/*@ requires number_arg: ¬\is_NaN(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1.571 ≤ \result ≤ 1.571; + assigns \result; + assigns \result \from x; + */ +extern double atan(double x); -extern char volatile __fc_hostname[64]; +/*@ requires number_arg: ¬\is_NaN(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1.571 ≤ \result ≤ 1.571; + assigns \result; + assigns \result \from x; + */ +extern long double atanl(long double x); -/*@ requires name_has_room: \valid(name + (0 .. len - 1)); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result, *(name + (0 .. len - 1)); - assigns \result - \from (indirect: __fc_hostname[0 .. len]), (indirect: len); - assigns *(name + (0 .. len - 1)) - \from (indirect: __fc_hostname[0 .. len]), (indirect: len); +/*@ requires number_args: ¬\is_NaN(x) ∧ ¬\is_NaN(y); + ensures finite_result: \is_finite(\result); + assigns \result; + assigns \result \from x, y; */ -extern int gethostname(char *name, size_t len); +extern double atan2(double y, double x); -/*@ requires name_valid_string: valid_read_nstring(name, len); - requires bounded_len: len ≤ 64; - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns __fc_hostname[0 .. len], \result; - assigns __fc_hostname[0 .. len] - \from *(name + (0 .. len - 1)), (indirect: len); - assigns \result \from (indirect: __fc_hostname[0 .. len]); +/*@ requires number_args: ¬\is_NaN(x) ∧ ¬\is_NaN(y); + ensures finite_result: \is_finite(\result); + assigns \result; + assigns \result \from x, y; */ -extern int sethostname(char const *name, size_t len); +extern float atan2f(float y, float x); -/*@ assigns \result; - assigns \result \from (indirect: pid); */ -extern pid_t getpgid(pid_t pid); - -/*@ assigns \result; - assigns \result \from \nothing; */ -extern pid_t getpgrp(void); - -/*@ assigns \result; - assigns \result \from \nothing; */ -extern pid_t getpid(void); - -/*@ assigns \result; - assigns \result \from \nothing; */ -extern pid_t getppid(void); - -/*@ assigns \result; - assigns \result \from \nothing; */ -extern pid_t getsid(pid_t __x0); - -/*@ assigns \result; - assigns \result \from \nothing; */ -extern uid_t getuid(void); - -/*@ ensures result_true_or_false: \result ≡ 0 ∨ \result ≡ 1; +/*@ requires number_args: ¬\is_NaN(x) ∧ ¬\is_NaN(y); + ensures finite_result: \is_finite(\result); assigns \result; - assigns \result \from (indirect: fd), (indirect: __fc_fds[fd]); + assigns \result \from x, y; */ -extern int isatty(int fd); +extern long double atan2l(long double y, long double x); -/*@ requires valid_path: valid_read_string(path1); - requires valid_path: valid_read_string(path2); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires finite_arg: \is_finite(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1. ≤ \result ≤ 1.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result - \from (indirect: *(path1 + (0 .. strlen{Old}(path1)))), - (indirect: *(path2 + (0 .. strlen{Old}(path2)))); - */ -extern int link(char const *path1, char const *path2); - -/*@ requires valid_fd: 0 ≤ fd < 1024; - requires valid_whence: whence ≡ 0 ∨ whence ≡ 1 ∨ whence ≡ 2; - ensures result_error_or_offset: \result ≡ -1 ∨ 0 ≤ \result; - assigns \result, __fc_fds[fd]; - assigns \result - \from (indirect: fd), (indirect: __fc_fds[fd]), (indirect: offset), - (indirect: whence); - assigns __fc_fds[fd] - \from (indirect: fd), __fc_fds[fd], (indirect: offset), - (indirect: whence); + assigns \result \from x; */ -extern off_t lseek(int fd, off_t offset, int whence); +extern double cos(double x); -/*@ requires valid_path: valid_read_string(path); +/*@ requires finite_arg: \is_finite(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1. ≤ \result ≤ 1.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from (indirect: *(path + (0 ..))), (indirect: name); - */ -extern long pathconf(char const *path, int name); - -/*@ requires valid_pipefd: \valid(pipefd + (0 .. 1)); - ensures initialization: pipefd: \initialized(\old(pipefd) + (0 .. 1)); - ensures valid_fd0: 0 ≤ *(\old(pipefd) + 0) < 1024; - ensures valid_fd1: 0 ≤ *(\old(pipefd) + 1) < 1024; - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns *(pipefd + (0 .. 1)), \result; - assigns *(pipefd + (0 .. 1)) \from (indirect: __fc_fds[0 ..]); - assigns \result \from (indirect: __fc_fds[0 ..]); - */ -extern int pipe(int pipefd[2]); - -/*@ requires valid_fd: 0 ≤ fd < 1024; - requires buf_has_room: \valid((char *)buf + (0 .. count - 1)); - assigns __fc_fds[fd], \result, *((char *)buf + (0 .. count - 1)); - assigns __fc_fds[fd] \from __fc_fds[fd]; - assigns \result \from (indirect: __fc_fds[fd]), (indirect: count); - assigns *((char *)buf + (0 .. count - 1)) - \from (indirect: __fc_fds[fd]), (indirect: count); - - behavior full_read: - assumes - nondet_small_count: - Frama_C_entropy_source ≢ 0 ∧ count ≤ 2147483647; - ensures res_full: \result ≡ \old(count); - ensures - res_init: initialization: - \initialized((char *)\old(buf) + (0 .. \old(count) - 1)); - - behavior large_read_implementation_defined: - assumes - nondet_large_count: - Frama_C_entropy_source ≢ 0 ∧ count > 2147483647; - ensures - res_init: initialization: - \initialized((char *)\old(buf) + (0 .. \old(count) - 1)); - - behavior partial_or_error: - assumes nondet: Frama_C_entropy_source ≡ 0; - ensures result_error_or_read_length: -1 ≤ \result < \old(count); - ensures - initialization: buf: - \initialized((char *)\old(buf) + (0 .. \result - 1)); - - complete behaviors partial_or_error, - large_read_implementation_defined, - full_read; - disjoint behaviors partial_or_error, - large_read_implementation_defined, - full_read; + assigns \result \from x; */ -extern ssize_t read(int fd, void *buf, size_t count); +extern float cosf(float x); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires finite_arg: \is_finite(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1. ≤ \result ≤ 1.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from (indirect: gid); + assigns \result \from x; */ -extern int setegid(gid_t gid); +extern long double cosl(long double x); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires finite_arg: \is_finite(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1. ≤ \result ≤ 1.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from (indirect: uid); + assigns \result \from x; */ -extern int seteuid(uid_t uid); +extern double sin(double x); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires finite_arg: \is_finite(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1. ≤ \result ≤ 1.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from (indirect: gid); + assigns \result \from x; */ -extern int setgid(gid_t gid); +extern float sinf(float x); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires finite_arg: \is_finite(x); + ensures finite_result: \is_finite(\result); + ensures result_domain: -1. ≤ \result ≤ 1.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from (indirect: pid), (indirect: pgid); + assigns \result \from x; */ -extern int setpgid(pid_t pid, pid_t pgid); +extern long double sinl(long double x); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result \from (indirect: rgid), (indirect: egid); +/*@ requires not_infinity: ¬(infinite_arg: \is_infinite(x)); + requires not_nan: ¬(nan_arg: \is_NaN(x)); + assigns __fc_errno, \result; + assigns __fc_errno \from x; + assigns \result \from x; + + behavior zero: + assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; + ensures zero_res: \is_finite(\result) ∧ \result ≡ \old(x); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + + behavior finite_non_zero: + assumes finite_arg: \is_finite(x) ∧ x ≢ 0.; + ensures finite_result: \is_finite(\result); + ensures + maybe_error: __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 34; + + complete behaviors finite_non_zero, zero; + disjoint behaviors finite_non_zero, zero; */ -extern int setregid(gid_t rgid, gid_t egid); +extern double tan(double x); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result \from (indirect: ruid), (indirect: euid); +/*@ requires not_infinity: ¬(infinite_arg: \is_infinite(x)); + requires not_nan: ¬(nan_arg: \is_NaN(x)); + assigns __fc_errno, \result; + assigns __fc_errno \from x; + assigns \result \from x; + + behavior zero: + assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; + ensures zero_res: \is_finite(\result) ∧ \result ≡ \old(x); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + + behavior finite_non_zero: + assumes finite_arg: \is_finite(x) ∧ x ≢ 0.; + ensures finite_result: \is_finite(\result); + ensures + maybe_error: __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 34; + + complete behaviors finite_non_zero, zero; + disjoint behaviors finite_non_zero, zero; */ -extern int setreuid(uid_t ruid, uid_t euid); +extern float tanf(float x); -/*@ ensures result_pgid_or_error: \result ≡ -1 ∨ \result ≥ 0; - assigns \result; - assigns \result \from \nothing; +/*@ ensures + maybe_error: + __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 33 ∨ + __fc_errno ≡ 34; + assigns __fc_errno, \result; + assigns __fc_errno \from x; + assigns \result \from x; */ -extern pid_t setsid(void); +extern long double tanl(long double x); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires in_domain: \is_finite(x) ∧ x ≥ 1; + ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from (indirect: uid); + assigns \result \from x; */ -extern int setuid(uid_t uid); +extern double acosh(double x); -/*@ ensures unslept: 0 ≤ \result ≤ \old(seconds); +/*@ requires in_domain: \is_finite(x) ∧ x ≥ 1; + ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from seconds; + assigns \result \from x; */ -extern unsigned int sleep(unsigned int seconds); - -/*@ assigns \nothing; */ -extern void sync(void); - -/*@ assigns \result; - assigns \result \from (indirect: name); */ -extern long sysconf(int name); +extern float acoshf(float x); -char volatile __fc_ttyname[32]; -char volatile *__fc_p_ttyname = __fc_ttyname; -/*@ requires valid_fildes: 0 ≤ fildes < 1024; - ensures - result_name_or_null: \result ≡ __fc_p_ttyname ∨ \result ≡ \null; +/*@ requires in_domain: \is_finite(x) ∧ x ≥ 1; + ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; + ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from __fc_p_ttyname, (indirect: fildes); + assigns \result \from x; */ -extern char *ttyname(int fildes); +extern long double acoshl(long double x); -/*@ requires valid_string_path: valid_read_string(path); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result \from (indirect: *(path + (0 .. strlen{Old}(path)))); +/*@ requires + not_overflow: + ¬(overflow_arg: \is_finite(x) ∧ x > 0x1.62e42fefa39efp+9); + requires not_plus_infinity: ¬(plus_infinity_arg: \is_plus_infinity(x)); + requires not_nan: ¬(nan_arg: \is_NaN(x)); + assigns __fc_errno, \result; + assigns __fc_errno \from x; + assigns \result \from x; + + behavior normal: + assumes finite_arg: \is_finite(x); + assumes + domain_arg: x ≥ -0x1.74910d52d3051p9 ∧ x ≤ 0x1.62e42fefa39efp+9; + ensures res_finite: \is_finite(\result); + ensures positive_result: \result > 0.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + + behavior underflow: + assumes underflow_arg: \is_finite(x) ∧ x < -0x1.74910d52d3051p9; + ensures zero_res: \result ≡ 0.; + ensures errno_set: __fc_errno ≡ 34; + + behavior minus_infinity: + assumes plus_infinity_arg: \is_minus_infinity(x); + ensures zero_result: \is_finite(\result) ∧ \result ≡ 0.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + + complete behaviors minus_infinity, underflow, normal; + disjoint behaviors minus_infinity, underflow, normal; */ -extern int unlink(char const *path); +extern double exp(double x); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result, Frama_C_entropy_source; - assigns \result - \from (indirect: usec), (indirect: Frama_C_entropy_source); - assigns Frama_C_entropy_source \from Frama_C_entropy_source; +/*@ requires + not_overflow: ¬(overflow_arg: \is_finite(x) ∧ x > 0x1.62e42ep+6); + requires not_plus_infinity: ¬(plus_infinity_arg: \is_plus_infinity(x)); + requires not_nan: ¬(nan_arg: \is_NaN(x)); + assigns __fc_errno, \result; + assigns __fc_errno \from x; + assigns \result \from x; + + behavior normal: + assumes finite_arg: \is_finite(x); + assumes domain_arg: x ≥ -0x1.9fe368p6 ∧ x ≤ 0x1.62e42ep+6; + ensures res_finite: \is_finite(\result); + ensures positive_result: \result > 0.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + + behavior underflow: + assumes underflow_arg: \is_finite(x) ∧ x < -0x1.9fe368p6; + ensures zero_res: \result ≡ 0.; + ensures errno_set: __fc_errno ≡ 34; + + behavior minus_infinity: + assumes plus_infinity_arg: \is_minus_infinity(x); + ensures zero_result: \is_finite(\result) ∧ \result ≡ 0.; + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + + complete behaviors minus_infinity, underflow, normal; + disjoint behaviors minus_infinity, underflow, normal; */ -extern int usleep(useconds_t usec); +extern float expf(float x); -/*@ requires valid_fd: 0 ≤ fd < 1024; - requires buf_has_room: \valid_read((char *)buf + (0 .. count - 1)); - ensures - result_error_or_written_bytes: - \result ≡ -1 ∨ (0 ≤ \result ≤ \old(count)); - assigns __fc_fds[fd], \result; - assigns __fc_fds[fd] - \from (indirect: fd), (indirect: count), __fc_fds[fd]; - assigns \result - \from (indirect: fd), (indirect: count), (indirect: __fc_fds[fd]); +/*@ requires valid_exp: \valid(exp); + requires + not_infinite: + ¬(infinite_arg: \is_plus_infinity(x) ∨ \is_minus_infinity(x)); + requires not_nan: ¬(nan_arg: \is_NaN(x)); + assigns \result, *exp; + assigns \result \from x; + assigns *exp \from x; + + behavior normal: + assumes finite_arg: \is_finite(x); + assumes arg_nonzero: x ≢ 0.0; + ensures finite_result: \is_finite(\result); + ensures bounded_result: 0.5 ≤ \result < 1.0; + ensures initialization: exp: \initialized(\old(exp)); + + behavior zero: + assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; + ensures finite_result: \is_finite(\result); + ensures zero_result: \result ≡ 0.0; + ensures initialization: exp: \initialized(\old(exp)); + ensures zero_exp: *\old(exp) ≡ 0; + + complete behaviors zero, normal; + disjoint behaviors zero, normal; */ -extern ssize_t write(int fd, void const *buf, size_t count); +extern double frexp(double x, int *exp); -/*@ requires valid_ruid: \valid(ruid); - requires valid_euid: \valid(suid); - requires valid_suid: \valid(euid); - ensures - initialization: result_ok_or_error: - (\result ≡ 0 ∧ \initialized(\old(ruid)) ∧ - \initialized(\old(euid)) ∧ \initialized(\old(suid))) ∨ - \result ≡ -1; - assigns *ruid, *euid, *suid, \result; - assigns *ruid \from \nothing; - assigns *euid \from \nothing; - assigns *suid \from \nothing; - assigns \result - \from (indirect: ruid), (indirect: euid), (indirect: suid); +/*@ requires valid_exp: \valid(exp); + requires + not_infinite: + ¬(infinite_arg: \is_plus_infinity(x) ∨ \is_minus_infinity(x)); + requires not_nan: ¬(nan_arg: \is_NaN(x)); + assigns \result, *exp; + assigns \result \from x; + assigns *exp \from x; + + behavior normal: + assumes finite_arg: \is_finite(x); + assumes arg_nonzero: x ≢ 0.0; + ensures finite_result: \is_finite(\result); + ensures bounded_result: 0.5 ≤ \result < 1.0; + ensures initialization: exp: \initialized(\old(exp)); + + behavior zero: + assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; + ensures finite_result: \is_finite(\result); + ensures zero_result: \result ≡ \old(x); + ensures initialization: exp: \initialized(\old(exp)); + ensures zero_exp: *\old(exp) ≡ 0; + + complete behaviors zero, normal; + disjoint behaviors zero, normal; */ -int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); +extern float frexpf(float x, int *exp); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result - \from (indirect: ruid), (indirect: euid), (indirect: suid); +/*@ requires valid_exp: \valid(exp); + requires + not_infinite: + ¬(infinite_arg: \is_plus_infinity(x) ∨ \is_minus_infinity(x)); + requires not_nan: ¬(nan_arg: \is_NaN(x)); + assigns \result, *exp; + assigns \result \from x; + assigns *exp \from x; + + behavior normal: + assumes finite_arg: \is_finite(x); + assumes arg_nonzero: x ≢ 0.0; + ensures finite_result: \is_finite(\result); + ensures bounded_result: 0.5 ≤ \result < 1.0; + ensures initialization: exp: \initialized(\old(exp)); + + behavior zero: + assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; + ensures finite_result: \is_finite(\result); + ensures zero_result: \result ≡ \old(x); + ensures initialization: exp: \initialized(\old(exp)); + ensures zero_exp: *\old(exp) ≡ 0; + + complete behaviors zero, normal; + disjoint behaviors zero, normal; */ -int setresuid(uid_t ruid, uid_t euid, uid_t suid); +extern long double frexpl(long double x, int *exp); -/*@ requires valid_rgid: \valid(rgid); - requires valid_egid: \valid(sgid); - requires valid_sgid: \valid(egid); +/*@ requires + finite_logic_res: + \is_finite((double)(x * pow((double)2.0d, (double)exp))); + ensures finite_result: \is_finite(\result); ensures - initialization: result_ok_or_error: - (\result ≡ 0 ∧ \initialized(\old(rgid)) ∧ - \initialized(\old(egid)) ∧ \initialized(\old(sgid))) ∨ - \result ≡ -1; - assigns *rgid, *egid, *sgid, \result; - assigns *rgid \from \nothing; - assigns *egid \from \nothing; - assigns *sgid \from \nothing; - assigns \result - \from (indirect: rgid), (indirect: egid), (indirect: sgid); + __fc_errno: __fc_errno ≡ 34 ∨ __fc_errno ≡ \old(__fc_errno); + assigns __fc_errno, \result; + assigns __fc_errno \from x, exp; + assigns \result \from x, exp; */ -int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); +extern double ldexp(double x, int exp); -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result - \from (indirect: rgid), (indirect: egid), (indirect: sgid); +/*@ requires + finite_logic_res: + \is_finite((float)(x * + pow((double)((float)2.0f), (double)((float)exp)))); + ensures finite_result: \is_finite(\result); + ensures + __fc_errno: __fc_errno ≡ 34 ∨ __fc_errno ≡ \old(__fc_errno); + assigns __fc_errno, \result; + assigns __fc_errno \from x, exp; + assigns \result \from x, exp; */ -int setresgid(gid_t rgid, gid_t egid, gid_t sgid); +extern float ldexpf(float x, int exp); -extern char *optarg; +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + */ +extern double log(double x); -int optind; +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + */ +extern float logf(float x); -extern int opterr; +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + */ +extern long double logl(long double x); -extern int optopt; +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + */ +extern double log10(double x); -/*@ assigns \result, *optarg, optind, opterr, optopt; - assigns \result - \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); - assigns *optarg - \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); - assigns optind - \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); - assigns opterr - \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); - assigns optopt - \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; */ -extern int getopt(int argc, char * const *argv, char const *optstring); +extern float log10f(float x); -/*@ assigns \result, *optarg, optind, opterr, optopt, - *((longopts + (0 ..))->flag); - assigns \result - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns *optarg - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns optind - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns opterr - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns optopt - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns *((longopts + (0 ..))->flag) - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; */ -extern int getopt_long(int argc, char * const *argv, char const *shortopts, - struct option const *longopts, int *longind); +extern long double log10l(long double x); -/*@ assigns \result, *optarg, optind, opterr, optopt, - *((longopts + (0 ..))->flag); - assigns \result - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns *optarg - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns optind - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns opterr - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns optopt - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); - assigns *((longopts + (0 ..))->flag) - \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), - *(longopts + (0 ..)); +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; */ -extern int getopt_long_only(int argc, char * const *argv, - char const *shortopts, - struct option const *longopts, int *longind); - -int optind = 1; -int glob(char const *pattern, int flags, - int (*errfunc)(char const *epath, int eerrno), glob_t *pglob); - -void globfree(glob_t *pglob); - -int glob(char const *pattern, int flags, - int (*errfunc)(char const *epath, int eerrno), glob_t *pglob) -{ - int __retres; - int tmp; - unsigned int tmp_0; - char **tmp_1; - int tmp_4; - tmp = Frama_C_interval(0,10); - pglob->gl_pathc = (unsigned int)tmp; - if (flags & (1 << 3)) tmp_0 = pglob->gl_offs; else tmp_0 = (unsigned int)0; - size_t reserve_offs = tmp_0; - size_t prev_len = (size_t)0; - if (flags & (1 << 5)) - while (*(pglob->gl_pathv + (reserve_offs + prev_len))) prev_len ++; - if (flags & (1 << 5)) tmp_1 = pglob->gl_pathv; else tmp_1 = (char **)0; - char **path = tmp_1; - if (pglob->gl_pathc == (unsigned int)0) - if (flags & (1 << 4)) { - pglob->gl_pathv = (char **)realloc((void *)path, - ((reserve_offs + prev_len) + (size_t)2) * sizeof(char *)); - if (! pglob->gl_pathv) { - __retres = 1; - goto return_label; - } - { - size_t i = (size_t)0; - while (i < reserve_offs) { - *(pglob->gl_pathv + i) = (char *)0; - i ++; - } - } - *(pglob->gl_pathv + (reserve_offs + prev_len)) = (char *)pattern; - *(pglob->gl_pathv + ((reserve_offs + prev_len) + (size_t)1)) = (char *)0; - __retres = 0; - goto return_label; - } - else { - __retres = 3; - goto return_label; - } - pglob->gl_pathv = (char **)realloc((void *)path, - (((reserve_offs + prev_len) + pglob->gl_pathc) + (size_t)1) * sizeof(char *)); - if (! pglob->gl_pathv) { - __retres = 1; - goto return_label; - } - { - size_t i_0 = (size_t)0; - while (i_0 < reserve_offs) { - *(pglob->gl_pathv + i_0) = (char *)0; - i_0 ++; - } - } - { - size_t i_1 = (size_t)0; - while (i_1 < pglob->gl_pathc) { - *(pglob->gl_pathv + ((reserve_offs + prev_len) + i_1)) = (char *)"glob result"; - i_1 ++; - } - } - *(pglob->gl_pathv + ((prev_len + reserve_offs) + pglob->gl_pathc)) = (char *)0; - tmp_4 = Frama_C_nondet(0,1); - if (tmp_4) { - __retres = 0; - goto return_label; - } - else { - if (errfunc) { - int tmp_3; - int tmp_2; - tmp_2 = Frama_C_interval(0,255); - tmp_3 = (*errfunc)("glob.c error path",tmp_2); - int res = tmp_3; - if (res) { - __retres = 2; - goto return_label; - } - else - if (flags & (1 << 0)) { - __retres = 2; - goto return_label; - } - } - __retres = 0; - goto return_label; - } - return_label: return __retres; -} +extern double log2(double x); -void globfree(glob_t *pglob) -{ - if (pglob->gl_pathc > (unsigned int)0) free((void *)pglob->gl_pathv); - return; -} +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + */ +extern float log2f(float x); -intmax_t imaxabs(intmax_t c); +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x > 0; + ensures finite_result: \is_finite(\result); + ensures no_error: __fc_errno ≡ \old(__fc_errno); + assigns \result; + assigns \result \from x; + */ +extern long double log2l(long double x); -imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom); +double fabs(double x); -/*@ assigns \result, *(endptr + (..)), __fc_errno; - assigns \result \from *(nptr + (..)), base; - assigns *(endptr + (..)) \from *(nptr + (..)), base; - assigns __fc_errno \from *(nptr + (..)), base; - */ -extern intmax_t strtoimax(char const * restrict nptr, - char ** restrict endptr, int base); +float fabsf(float x); -/*@ requires abs_representable: c > -9223372036854775807LL - 1LL; +/*@ requires finite_arg: \is_finite(x); + ensures res_finite: \is_finite(\result); ensures positive_result: \result ≥ 0.; ensures - equal_magnitude_result: \result ≡ \old(c) ∨ \result ≡ -\old(c); - ensures logical_abs_result: \result ≡ \abs(\old(c)); + equal_magnitude_result: \result ≡ \old(x) ∨ \result ≡ -\old(x); assigns \result; - assigns \result \from c; + assigns \result \from x; */ -intmax_t imaxabs(intmax_t c) -{ - intmax_t __retres; - if (c > (intmax_t)0) { - __retres = c; - goto return_label; - } - else { - __retres = - c; - goto return_label; - } - return_label: return __retres; -} +extern long double fabsl(long double x); -/*@ requires no_div_by_zero: denom ≢ 0; - requires no_overflow: denom ≢ -1 ∨ (intmax_t)(-numer) ≢ numer; - ensures correct_div: \result.quot ≡ \old(numer) / \old(denom); - ensures correct_mod: \result.rem ≡ \old(numer) % \old(denom); - assigns \result; - assigns \result \from numer, denom; +/*@ requires finite_logic_res: \is_finite(pow(x, y)); + ensures finite_result: \is_finite(\result); + ensures + __fc_errno: __fc_errno ≡ 34 ∨ __fc_errno ≡ \old(__fc_errno); + assigns __fc_errno, \result; + assigns __fc_errno \from x, y; + assigns \result \from x, y; */ -imaxdiv_t imaxdiv(intmax_t numer, intmax_t denom) -{ - imaxdiv_t r; - r.quot = numer / denom; - r.rem = numer % denom; - return r; -} - -extern struct lconv *__fc_locale; - -extern char *__fc_locale_names[512]; - -char *setlocale(int category, char const *locale); - -struct lconv *localeconv(void); +extern double pow(double x, double y); -struct lconv __C_locale = - {.decimal_point = (char *)".", - .thousands_sep = (char *)"", - .grouping = (char *)"", - .int_curr_symbol = (char *)"", - .currency_symbol = (char *)"", - .mon_decimal_point = (char *)"", - .mon_thousands_sep = (char *)"", - .mon_grouping = (char *)"", - .positive_sign = (char *)"", - .negative_sign = (char *)"", - .int_frac_digits = (char)127, - .frac_digits = (char)127, - .p_cs_precedes = (char)127, - .p_sep_by_space = (char)127, - .n_cs_precedes = (char)127, - .n_sep_by_space = (char)127, - .p_sign_posn = (char)127, - .n_sign_posn = (char)127, - .int_p_cs_precedes = (char)127, - .int_p_sep_by_space = (char)127, - .int_n_cs_precedes = (char)127, - .int_n_sep_by_space = (char)127, - .int_p_sign_posn = (char)127, - .int_n_sign_posn = (char)127}; -struct lconv *__frama_c_locale = & __C_locale; -char const *__frama_c_locale_names[512] = {"C"}; -/*@ requires - locale_null_or_valid_string: - locale ≡ \null ∨ valid_read_string(locale); +/*@ requires finite_logic_res: \is_finite(pow((double)x, (double)y)); + ensures finite_result: \is_finite(\result); ensures - result_null_or_locale_name: - \result ≡ \null ∨ - (\valid(\result) ∧ (∃ ℤ i; \result ≡ __fc_locale_names[i])); - assigns __fc_locale, \result; - assigns __fc_locale \from category, *(locale + (..)); - assigns \result \from __fc_locale, category, *(locale + (..)); - */ -char *setlocale(int category, char const *locale) -{ - char *__retres; - if ((int)*locale == 'C') { - __frama_c_locale = & __C_locale; - __retres = (char *)__frama_c_locale_names[0]; - goto return_label; - } - __retres = (char *)0; - return_label: return __retres; -} - -/*@ ensures result_current_locale: \result ≡ __fc_locale; - assigns \result; - assigns \result \from __fc_locale; - */ -struct lconv *localeconv(void) -{ - return __frama_c_locale; -} - -/*@ assigns \result; - assigns \result \from x; - - behavior nan: - assumes is_nan: \is_NaN(x); - ensures fp_nan: \result ≡ 0; - - behavior inf: - assumes is_infinite: ¬\is_NaN(x) ∧ ¬\is_finite(x); - ensures fp_infinite: \result ≡ 1; - - behavior zero: - assumes is_a_zero: x ≡ 0.0; - ensures fp_zero: \result ≡ 2; - - behavior subnormal: - assumes is_finite: \is_finite(x); - assumes - is_subnormal: - (x > 0.0 ∧ x < 0x1p-126) ∨ (x < 0.0 ∧ x > -0x1p-126); - ensures fp_subnormal: \result ≡ 3; - - behavior normal: - assumes is_finite: \is_finite(x); - assumes not_subnormal: x ≤ -0x1p-126 ∨ x ≥ 0x1p-126; - ensures fp_normal: \result ≡ 4; - - complete behaviors normal, subnormal, zero, inf, nan; - disjoint behaviors normal, subnormal, zero, inf, nan; - */ -int __fc_fpclassifyf(float x); - -/*@ assigns \result; - assigns \result \from x; - - behavior nan: - assumes is_nan: \is_NaN(x); - ensures fp_nan: \result ≡ 0; - - behavior inf: - assumes is_infinite: ¬\is_NaN(x) ∧ ¬\is_finite(x); - ensures fp_infinite: \result ≡ 1; - - behavior zero: - assumes is_a_zero: x ≡ 0.0; - ensures fp_zero: \result ≡ 2; - - behavior subnormal: - assumes is_finite: \is_finite(x); - assumes - is_subnormal: - (x > 0.0 ∧ x < 0x1p-1022) ∨ (x < 0.0 ∧ x > -0x1p-1022); - ensures fp_subnormal: \result ≡ 3; - - behavior normal: - assumes is_finite: \is_finite(x); - assumes not_subnormal: x ≤ -0x1p-1022 ∨ x ≥ 0x1p-1022; - ensures fp_normal: \result ≡ 4; - - complete behaviors normal, subnormal, zero, inf, nan; - disjoint behaviors normal, subnormal, zero, inf, nan; + __fc_errno: __fc_errno ≡ 34 ∨ __fc_errno ≡ \old(__fc_errno); + assigns __fc_errno, \result; + assigns __fc_errno \from x, y; + assigns \result \from x, y; */ -int __fc_fpclassify(double x); +extern float powf(float x, float y); -/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; - ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x ≥ -0.; + ensures finite_result: \is_finite(\result); + ensures positive_result: \result ≥ -0.; + ensures result_value: \result ≡ sqrt(\old(x)); ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern double acos(double x); +extern double sqrt(double x); -/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; - ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x ≥ -0.; + ensures finite_result: \is_finite(\result); + ensures positive_result: \result ≥ -0.; + ensures result_value: \result ≡ sqrt((double)\old(x)); ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern float acosf(float x); +extern float sqrtf(float x); -/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; - ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; +/*@ requires finite_arg: \is_finite(x); + requires arg_positive: x ≥ -0.; + ensures finite_result: \is_finite(\result); + ensures positive_result: \result ≥ -0.; ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern long double acosl(long double x); +extern long double sqrtl(long double x); -/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern double asin(double x); +extern double ceil(double x); -/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern float asinf(float x); +extern float ceilf(float x); -/*@ requires in_domain: \is_finite(x) ∧ \abs(x) ≤ 1; +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern long double asinl(long double x); +extern long double ceill(long double x); -/*@ requires number_arg: ¬\is_NaN(x); +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures result_domain: -1.571 ≤ \result ≤ 1.571; assigns \result; assigns \result \from x; */ -extern float atanf(float x); +extern double floor(double x); -/*@ requires number_arg: ¬\is_NaN(x); +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures result_domain: -1.571 ≤ \result ≤ 1.571; assigns \result; assigns \result \from x; */ -extern double atan(double x); +extern float floorf(float x); -/*@ requires number_arg: ¬\is_NaN(x); +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures result_domain: -1.571 ≤ \result ≤ 1.571; assigns \result; assigns \result \from x; */ -extern long double atanl(long double x); +extern long double floorl(long double x); -/*@ requires number_args: ¬\is_NaN(x) ∧ ¬\is_NaN(y); +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); assigns \result; - assigns \result \from x, y; + assigns \result \from x; */ -extern double atan2(double y, double x); +extern double round(double x); -/*@ requires number_args: ¬\is_NaN(x) ∧ ¬\is_NaN(y); +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); assigns \result; - assigns \result \from x, y; + assigns \result \from x; */ -extern float atan2f(float y, float x); +extern float roundf(float x); -/*@ requires number_args: ¬\is_NaN(x) ∧ ¬\is_NaN(y); +/*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); assigns \result; - assigns \result \from x, y; + assigns \result \from x; */ -extern long double atan2l(long double y, long double x); +extern long double roundl(long double x); /*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures result_domain: -1. ≤ \result ≤ 1.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern double cos(double x); +extern double trunc(double x); /*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures result_domain: -1. ≤ \result ≤ 1.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern float cosf(float x); +extern float truncf(float x); /*@ requires finite_arg: \is_finite(x); ensures finite_result: \is_finite(\result); - ensures result_domain: -1. ≤ \result ≤ 1.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; assigns \result \from x; */ -extern long double cosl(long double x); +extern long double truncl(long double x); -/*@ requires finite_arg: \is_finite(x); +/*@ requires in_domain: ¬\is_NaN(x) ∧ ¬\is_NaN(y) ∧ y ≢ 0.; ensures finite_result: \is_finite(\result); - ensures result_domain: -1. ≤ \result ≤ 1.; ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from x; + assigns \result \from x, y; */ -extern double sin(double x); +extern double fmod(double x, double y); -/*@ requires finite_arg: \is_finite(x); +/*@ requires in_domain: ¬\is_NaN(x) ∧ ¬\is_NaN(y) ∧ y ≢ 0.; ensures finite_result: \is_finite(\result); - ensures result_domain: -1. ≤ \result ≤ 1.; ensures no_error: __fc_errno ≡ \old(__fc_errno); assigns \result; - assigns \result \from x; + assigns \result \from x, y; */ -extern float sinf(float x); +extern float fmodf(float x, float y); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - ensures result_domain: -1. ≤ \result ≤ 1.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); +/*@ requires tagp_valid_string: valid_read_string(tagp); + ensures result_is_nan: \is_NaN(\result); assigns \result; - assigns \result \from x; + assigns \result \from (indirect: *(tagp + (0 ..))); */ -extern long double sinl(long double x); +extern double nan(char const *tagp); -/*@ requires not_infinity: ¬(infinite_arg: \is_infinite(x)); - requires not_nan: ¬(nan_arg: \is_NaN(x)); - assigns __fc_errno, \result; - assigns __fc_errno \from x; - assigns \result \from x; - - behavior zero: - assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; - ensures zero_res: \is_finite(\result) ∧ \result ≡ \old(x); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; - - behavior finite_non_zero: - assumes finite_arg: \is_finite(x) ∧ x ≢ 0.; - ensures finite_result: \is_finite(\result); - ensures - maybe_error: __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 34; - - complete behaviors finite_non_zero, zero; - disjoint behaviors finite_non_zero, zero; +/*@ requires tagp_valid_string: valid_read_string(tagp); + ensures result_is_nan: \is_NaN(\result); + assigns \result; + assigns \result \from (indirect: *(tagp + (0 ..))); */ -extern double tan(double x); +extern float nanf(char const *tagp); -/*@ requires not_infinity: ¬(infinite_arg: \is_infinite(x)); - requires not_nan: ¬(nan_arg: \is_NaN(x)); - assigns __fc_errno, \result; - assigns __fc_errno \from x; - assigns \result \from x; - - behavior zero: - assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; - ensures zero_res: \is_finite(\result) ∧ \result ≡ \old(x); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; - - behavior finite_non_zero: - assumes finite_arg: \is_finite(x) ∧ x ≢ 0.; - ensures finite_result: \is_finite(\result); - ensures - maybe_error: __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 34; - - complete behaviors finite_non_zero, zero; - disjoint behaviors finite_non_zero, zero; +/*@ requires tagp_valid_string: valid_read_string(tagp); + ensures result_is_nan: \is_NaN(\result); + assigns \result; + assigns \result \from (indirect: *(tagp + (0 ..))); */ -extern float tanf(float x); +extern long double nanl(char const *tagp); -/*@ ensures - maybe_error: - __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 33 ∨ - __fc_errno ≡ 34; - assigns __fc_errno, \result; - assigns __fc_errno \from x; - assigns \result \from x; +int __finitef(float f); + +int __finite(double d); + +/*@ logic float __fc_infinity(ℤ x) = \plus_infinity; */ -extern long double tanl(long double x); +/*@ logic float __fc_nan(ℤ x) = \NaN; -/*@ requires in_domain: \is_finite(x) ∧ x ≥ 1; - ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; - ensures no_error: __fc_errno ≡ \old(__fc_errno); +*/ +/*@ ensures result_is_infinity: \is_plus_infinity(\result); assigns \result; - assigns \result \from x; + assigns \result \from \nothing; */ -extern double acosh(double x); +extern float __fc_infinity(int x); -/*@ requires in_domain: \is_finite(x) ∧ x ≥ 1; - ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; - ensures no_error: __fc_errno ≡ \old(__fc_errno); +/*@ ensures result_is_nan: \is_NaN(\result); assigns \result; - assigns \result \from x; + assigns \result \from \nothing; */ -extern float acoshf(float x); +extern float __fc_nan(int x); -/*@ requires in_domain: \is_finite(x) ∧ x ≥ 1; - ensures positive_result: \is_finite(\result) ∧ \result ≥ 0; - ensures no_error: __fc_errno ≡ \old(__fc_errno); +/*@ requires finite_arg: \is_finite(x); + ensures res_finite: \is_finite(\result); + ensures positive_result: \result ≥ 0.; + ensures + equal_magnitude_result: \result ≡ \old(x) ∨ \result ≡ -\old(x); assigns \result; assigns \result \from x; */ -extern long double acoshl(long double x); +double fabs(double x) +{ + double __retres; + if (x == 0.0) { + __retres = 0.0; + goto return_label; + } + if (x > 0.0) { + __retres = x; + goto return_label; + } + __retres = - x; + return_label: return __retres; +} -/*@ requires - not_overflow: - ¬(overflow_arg: \is_finite(x) ∧ x > 0x1.62e42fefa39efp+9); - requires not_plus_infinity: ¬(plus_infinity_arg: \is_plus_infinity(x)); - requires not_nan: ¬(nan_arg: \is_NaN(x)); - assigns __fc_errno, \result; - assigns __fc_errno \from x; +/*@ requires finite_arg: \is_finite(x); + ensures res_finite: \is_finite(\result); + ensures positive_result: \result ≥ 0.; + ensures + equal_magnitude_result: \result ≡ \old(x) ∨ \result ≡ -\old(x); + assigns \result; assigns \result \from x; - - behavior normal: - assumes finite_arg: \is_finite(x); - assumes - domain_arg: x ≥ -0x1.74910d52d3051p9 ∧ x ≤ 0x1.62e42fefa39efp+9; - ensures res_finite: \is_finite(\result); - ensures positive_result: \result > 0.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; - - behavior underflow: - assumes underflow_arg: \is_finite(x) ∧ x < -0x1.74910d52d3051p9; - ensures zero_res: \result ≡ 0.; - ensures errno_set: __fc_errno ≡ 34; - - behavior minus_infinity: - assumes plus_infinity_arg: \is_minus_infinity(x); - ensures zero_result: \is_finite(\result) ∧ \result ≡ 0.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; - - complete behaviors minus_infinity, underflow, normal; - disjoint behaviors minus_infinity, underflow, normal; */ -extern double exp(double x); +float fabsf(float x) +{ + float __retres; + if (x == 0.0f) { + __retres = 0.0f; + goto return_label; + } + else + if (x > 0.0f) { + __retres = x; + goto return_label; + } + else { + __retres = - x; + goto return_label; + } + return_label: return __retres; +} -/*@ requires - not_overflow: ¬(overflow_arg: \is_finite(x) ∧ x > 0x1.62e42ep+6); - requires not_plus_infinity: ¬(plus_infinity_arg: \is_plus_infinity(x)); - requires not_nan: ¬(nan_arg: \is_NaN(x)); - assigns __fc_errno, \result; - assigns __fc_errno \from x; - assigns \result \from x; - - behavior normal: - assumes finite_arg: \is_finite(x); - assumes domain_arg: x ≥ -0x1.9fe368p6 ∧ x ≤ 0x1.62e42ep+6; - ensures res_finite: \is_finite(\result); - ensures positive_result: \result > 0.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; +/*@ assigns \result; + assigns \result \from f; - behavior underflow: - assumes underflow_arg: \is_finite(x) ∧ x < -0x1.9fe368p6; - ensures zero_res: \result ≡ 0.; - ensures errno_set: __fc_errno ≡ 34; + behavior finite: + assumes isfinite_f: \is_finite(f); + ensures nonzero_result: \result > 0 ∨ \result < 0; - behavior minus_infinity: - assumes plus_infinity_arg: \is_minus_infinity(x); - ensures zero_result: \is_finite(\result) ∧ \result ≡ 0.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; + behavior nonfinite: + assumes nonfinite_f: ¬\is_finite(f); + ensures zero_result: \result ≡ 0; - complete behaviors minus_infinity, underflow, normal; - disjoint behaviors minus_infinity, underflow, normal; + complete behaviors nonfinite, finite; + disjoint behaviors nonfinite, finite; */ -extern float expf(float x); +int __finitef(float f) +{ + int __retres; + union __fc_u_finitef u; + unsigned short usExp; + u.f = f; + usExp = (unsigned short)((int)u.w[1] & 0x7F80); + usExp = (unsigned short)((int)usExp >> 7); + __retres = ! ((int)usExp == 0xff); + return __retres; +} -/*@ requires valid_exp: \valid(exp); - requires - not_infinite: - ¬(infinite_arg: \is_plus_infinity(x) ∨ \is_minus_infinity(x)); - requires not_nan: ¬(nan_arg: \is_NaN(x)); - assigns \result, *exp; - assigns \result \from x; - assigns *exp \from x; +/*@ assigns \result; + assigns \result \from d; - behavior normal: - assumes finite_arg: \is_finite(x); - assumes arg_nonzero: x ≢ 0.0; - ensures finite_result: \is_finite(\result); - ensures bounded_result: 0.5 ≤ \result < 1.0; - ensures initialization: exp: \initialized(\old(exp)); + behavior finite: + assumes isfinite_d: \is_finite(d); + ensures nonzero_result: \result > 0 ∨ \result < 0; - behavior zero: - assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; - ensures finite_result: \is_finite(\result); - ensures zero_result: \result ≡ 0.0; - ensures initialization: exp: \initialized(\old(exp)); - ensures zero_exp: *\old(exp) ≡ 0; + behavior nonfinite: + assumes nonfinite_d: ¬\is_finite(d); + ensures zero_result: \result ≡ 0; - complete behaviors zero, normal; - disjoint behaviors zero, normal; + complete behaviors nonfinite, finite; + disjoint behaviors nonfinite, finite; */ -extern double frexp(double x, int *exp); +int __finite(double d) +{ + int __retres; + union __fc_u_finite u; + unsigned short usExp; + u.d = d; + usExp = (unsigned short)((int)u.w[3] & 0x7F80); + usExp = (unsigned short)((int)usExp >> 7); + __retres = ! ((int)usExp == 0xff); + return __retres; +} -/*@ requires valid_exp: \valid(exp); - requires - not_infinite: - ¬(infinite_arg: \is_plus_infinity(x) ∨ \is_minus_infinity(x)); - requires not_nan: ¬(nan_arg: \is_NaN(x)); - assigns \result, *exp; - assigns \result \from x; - assigns *exp \from x; - - behavior normal: - assumes finite_arg: \is_finite(x); - assumes arg_nonzero: x ≢ 0.0; - ensures finite_result: \is_finite(\result); - ensures bounded_result: 0.5 ≤ \result < 1.0; - ensures initialization: exp: \initialized(\old(exp)); - - behavior zero: - assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; - ensures finite_result: \is_finite(\result); - ensures zero_result: \result ≡ \old(x); - ensures initialization: exp: \initialized(\old(exp)); - ensures zero_exp: *\old(exp) ≡ 0; - - complete behaviors zero, normal; - disjoint behaviors zero, normal; - */ -extern float frexpf(float x, int *exp); - -/*@ requires valid_exp: \valid(exp); - requires - not_infinite: - ¬(infinite_arg: \is_plus_infinity(x) ∨ \is_minus_infinity(x)); - requires not_nan: ¬(nan_arg: \is_NaN(x)); - assigns \result, *exp; - assigns \result \from x; - assigns *exp \from x; - - behavior normal: - assumes finite_arg: \is_finite(x); - assumes arg_nonzero: x ≢ 0.0; - ensures finite_result: \is_finite(\result); - ensures bounded_result: 0.5 ≤ \result < 1.0; - ensures initialization: exp: \initialized(\old(exp)); - - behavior zero: - assumes zero_arg: \is_finite(x) ∧ x ≡ 0.; - ensures finite_result: \is_finite(\result); - ensures zero_result: \result ≡ \old(x); - ensures initialization: exp: \initialized(\old(exp)); - ensures zero_exp: *\old(exp) ≡ 0; - - complete behaviors zero, normal; - disjoint behaviors zero, normal; - */ -extern long double frexpl(long double x, int *exp); +/*@ assigns \nothing; */ +extern void (*signal(int sig, void (*func)(int )))(int ); -/*@ requires - finite_logic_res: - \is_finite((double)(x * pow((double)2.0d, (double)exp))); - ensures finite_result: \is_finite(\result); - ensures - __fc_errno: __fc_errno ≡ 34 ∨ __fc_errno ≡ \old(__fc_errno); - assigns __fc_errno, \result; - assigns __fc_errno \from x, exp; - assigns \result \from x, exp; - */ -extern double ldexp(double x, int exp); +/*@ ensures never_terminates: \false; + assigns \nothing; */ +extern int raise(int sig); -/*@ requires - finite_logic_res: - \is_finite((float)(x * - pow((double)((float)2.0f), (double)((float)exp)))); - ensures finite_result: \is_finite(\result); - ensures - __fc_errno: __fc_errno ≡ 34 ∨ __fc_errno ≡ \old(__fc_errno); - assigns __fc_errno, \result; - assigns __fc_errno \from x, exp; - assigns \result \from x, exp; +/*@ requires valid_set: \valid(set); + ensures initialization: set: \initialized(\old(set)); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns *set, \result; + assigns *set \from \nothing; + assigns \result \from \nothing; */ -extern float ldexpf(float x, int exp); +extern int sigemptyset(sigset_t *set); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; +/*@ requires valid_set: \valid(set); + ensures initialization: set: \initialized(\old(set)); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns *set, \result; + assigns *set \from \nothing; + assigns \result \from \nothing; */ -extern double log(double x); +extern int sigfillset(sigset_t *set); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; +/*@ requires valid_set: \valid(set); + requires initialization: set: \initialized(set); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns *set, \result; + assigns *set \from (indirect: signum); + assigns \result \from signum; */ -extern float logf(float x); +extern int sigaddset(sigset_t *set, int signum); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; +/*@ requires valid_set: \valid(set); + requires initialization: set: \initialized(set); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns *set, \result; + assigns *set \from (indirect: signum); + assigns \result \from signum; */ -extern long double logl(long double x); +extern int sigdelset(sigset_t *set, int signum); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); +/*@ requires valid_read_set: \valid_read(set); + requires initialization: set: \initialized(set); + ensures + result_found_not_found_or_error: + \result ≡ 0 ∨ \result ≡ 1 ∨ \result ≡ -1; assigns \result; - assigns \result \from x; + assigns \result \from *set, signum; */ -extern double log10(double x); +extern int sigismember(sigset_t const *set, int signum); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; +struct sigaction __fc_sigaction[64 + 1]; +struct sigaction *__fc_p_sigaction = __fc_sigaction; +/*@ requires valid_signal: 0 ≤ signum ≤ 64; + requires valid_oldact_or_null: oldact ≡ \null ∨ \valid(oldact); + requires valid_read_act_or_null: act ≡ \null ∨ \valid_read(act); + requires separation: separated_acts: \separated(act, oldact); + ensures + act_changed: + \old(act) ≡ \null ∨ + \subset(*(__fc_p_sigaction + \old(signum)), *\old(act)); + ensures + oldact_assigned: + \old(oldact) ≡ \null ∨ + *\old(oldact) ∈ *(__fc_p_sigaction + \old(signum)); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns *oldact, *(__fc_p_sigaction + signum), \result; + assigns *oldact \from __fc_p_sigaction; + assigns *(__fc_p_sigaction + signum) \from *act; + assigns \result + \from (indirect: signum), (indirect: act), (indirect: *act), + (indirect: oldact), (indirect: *oldact); */ -extern float log10f(float x); +extern int sigaction(int signum, struct sigaction const * restrict act, + struct sigaction * restrict oldact); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; +/*@ requires valid_set_or_null: set ≡ \null ∨ \valid_read(set); + requires valid_how: set ≢ \null ⇒ how ∈ {0, 2, 1}; + requires valid_oldset_or_null: oldset ≡ \null ∨ \valid(oldset); + requires + separation: (set ≡ oldset ≡ \null) ∨ \separated(set, oldset); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + ensures + initialization: oldset_initialized: + \old(oldset) ≢ \null ∧ \result ≡ 0 ⇒ + \initialized(\old(oldset)); + assigns \result, *oldset; + assigns \result + \from (indirect: how), (indirect: set), (indirect: oldset); + assigns *oldset \from (indirect: how), (indirect: oldset); */ -extern long double log10l(long double x); +extern int sigprocmask(int how, sigset_t const * restrict set, + sigset_t * restrict oldset); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; +/*@ requires valid_mask_or_null: sigmask ≡ \null ∨ \valid_read(sigmask); + ensures result_means_interrupted: \result ≡ -1; + ensures errno_set: __fc_errno ≡ 4; + assigns __fc_errno, \result; + assigns __fc_errno \from (indirect: sigmask); + assigns \result \from (indirect: sigmask); */ -extern double log2(double x); +extern int sigsuspend(sigset_t const *sigmask); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns \result; - assigns \result \from x; + assigns \result \from (indirect: pid), (indirect: sig); */ -extern float log2f(float x); +extern int kill(pid_t pid, int sig); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x > 0; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns \result; - assigns \result \from x; + assigns \result \from (indirect: pgrp), (indirect: sig); */ -extern long double log2l(long double x); - -double fabs(double x); +extern int killpg(pid_t pgrp, int sig); -float fabsf(float x); +extern int volatile __fc_fds[1024]; -/*@ requires finite_arg: \is_finite(x); - ensures res_finite: \is_finite(\result); - ensures positive_result: \result ≥ 0.; +/*@ requires valid_fd: 0 ≤ fd < 1024; + requires + initialization: initialized_inputs: + ∀ ℤ i; + 0 ≤ i < iovcnt ⇒ + \initialized(&(iov + i)->iov_base) ∧ + \initialized(&(iov + i)->iov_len); + requires + valid_iov: + ∀ ℤ i; + 0 ≤ i < iovcnt ⇒ + \valid((char *)(&(iov + i)->iov_base) + + (0 .. (iov + i)->iov_len - 1)); + requires bounded_iovcnt: 0 ≤ iovcnt ≤ 1024; ensures - equal_magnitude_result: \result ≡ \old(x) ∨ \result ≡ -\old(x); - assigns \result; - assigns \result \from x; + result_error_or_read_bytes: + \result ≡ -1 ∨ + (0 ≤ \result ≤ + \sum(0, \old(iovcnt) - 1, \lambda ℤ k; (\old(iov) + k)->iov_len)); + assigns {*((char *)(iov + i)->iov_base + j) | + ℤ i, ℤ j; 0 ≤ i < iovcnt ∧ 0 ≤ j < (iov + i)->iov_len}, + \result; + assigns + {*((char *)(iov + i)->iov_base + j) | + ℤ i, ℤ j; 0 ≤ i < iovcnt ∧ 0 ≤ j < (iov + i)->iov_len} + \from (indirect: fd), (indirect: iovcnt), (indirect: __fc_fds[fd]); + assigns \result + \from (indirect: fd), (indirect: __fc_fds[fd]), + (indirect: *(iov + (0 ..))), (indirect: iovcnt); */ -extern long double fabsl(long double x); +extern ssize_t readv(int fd, struct iovec const *iov, int iovcnt); -/*@ requires finite_logic_res: \is_finite(pow(x, y)); - ensures finite_result: \is_finite(\result); - ensures - __fc_errno: __fc_errno ≡ 34 ∨ __fc_errno ≡ \old(__fc_errno); - assigns __fc_errno, \result; - assigns __fc_errno \from x, y; - assigns \result \from x, y; - */ -extern double pow(double x, double y); - -/*@ requires finite_logic_res: \is_finite(pow((double)x, (double)y)); - ensures finite_result: \is_finite(\result); +/*@ requires valid_fd: 0 ≤ fd < 1024; + requires + initialization: initialized_inputs: + ∀ ℤ i; + 0 ≤ i < iovcnt ⇒ + \initialized(&(iov + i)->iov_base) ∧ + \initialized(&(iov + i)->iov_len); + requires valid_read_iov: \valid_read(iov + (0 .. iovcnt - 1)); + requires + valid_read_iov_bases: + ∀ ℤ i; + 0 ≤ i < iovcnt ⇒ + \valid_read((char *)(iov + i)->iov_base + + (0 .. (iov + i)->iov_len - 1)); + requires bounded_iovcnt: 0 ≤ iovcnt ≤ 1024; + requires + bounded_lengths: + \sum(0, iovcnt - 1, \lambda ℤ k; (iov + k)->iov_len) ≤ 2147483647; ensures - __fc_errno: __fc_errno ≡ 34 ∨ __fc_errno ≡ \old(__fc_errno); - assigns __fc_errno, \result; - assigns __fc_errno \from x, y; - assigns \result \from x, y; - */ -extern float powf(float x, float y); - -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x ≥ -0.; - ensures finite_result: \is_finite(\result); - ensures positive_result: \result ≥ -0.; - ensures result_value: \result ≡ sqrt(\old(x)); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; - */ -extern double sqrt(double x); - -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x ≥ -0.; - ensures finite_result: \is_finite(\result); - ensures positive_result: \result ≥ -0.; - ensures result_value: \result ≡ sqrt((double)\old(x)); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; + result_error_or_written_bytes: + \result ≡ -1 ∨ + (0 ≤ \result ≤ + \sum(0, \old(iovcnt) - 1, \lambda ℤ k; (\old(iov) + k)->iov_len)); + assigns \result, __fc_fds[fd]; + assigns \result + \from (indirect: fd), (indirect: __fc_fds[fd]), + (indirect: *(iov + (0 ..))), (indirect: iovcnt); + assigns __fc_fds[fd] + \from (indirect: *(iov + (0 ..))), (indirect: iovcnt); */ -extern float sqrtf(float x); +extern ssize_t writev(int fd, struct iovec const *iov, int iovcnt); -/*@ requires finite_arg: \is_finite(x); - requires arg_positive: x ≥ -0.; - ensures finite_result: \is_finite(\result); - ensures positive_result: \result ≥ -0.; - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x; - */ -extern long double sqrtl(long double x); +/*@ ghost struct __fc_sockfds_type __fc_sockfds[1024]; */ +/*@ ghost extern int __fc_socket_counter; */ -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ ghost int volatile __fc_open_sock_fds; */ +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + ensures + result_error_or_valid_new_sockfd: + \result ≡ -1 ∨ (0 ≤ \result < 1024); + assigns \result, *((char *)addr + (0 .. *addrlen - 1)), + __fc_sockfds[sockfd]; + assigns \result \from *addr, *addrlen, __fc_sockfds[sockfd]; + assigns *((char *)addr + (0 .. *addrlen - 1)) + \from *addr, *addrlen, __fc_sockfds[sockfd]; + assigns __fc_sockfds[sockfd] \from *addr, *addrlen, __fc_sockfds[sockfd]; + + behavior addr_null: + assumes addr_is_null: addr ≡ \null; + requires addrlen_should_be_null: addrlen ≡ \null; + assigns \result, __fc_sockfds[sockfd]; + assigns \result \from __fc_sockfds[sockfd]; + assigns __fc_sockfds[sockfd] \from __fc_sockfds[sockfd]; + + behavior addr_not_null: + assumes addr_is_not_null: addr ≢ \null; + requires valid_addrlen: \valid(addrlen); + requires addr_has_room: \valid((char *)addr + (0 .. *addrlen - 1)); + ensures + initialization: addr: + \initialized((char *)\old(addr) + (0 .. *\old(addrlen) - 1)); + + disjoint behaviors addr_not_null, addr_null; */ -extern double ceil(double x); +extern int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires valid_sockfd: sockfd: 0 ≤ sockfd < 1024; + requires valid_read_addr: \valid_read((char *)addr + (0 .. addrlen - 1)); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns __fc_sockfds[sockfd], \result; + assigns __fc_sockfds[sockfd] + \from sockfd, *addr, addrlen, __fc_sockfds[sockfd]; + assigns \result + \from (indirect: sockfd), (indirect: *addr), (indirect: addrlen), + (indirect: __fc_sockfds[sockfd]); */ -extern float ceilf(float x); +extern int bind(int sockfd, struct sockaddr const *addr, socklen_t addrlen); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + requires valid_read_addr: \valid_read((char *)addr + (0 .. addrlen - 1)); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns __fc_sockfds[sockfd], \result; + assigns __fc_sockfds[sockfd] + \from __fc_sockfds[sockfd], (indirect: sockfd), (indirect: addr), + (indirect: *addr), (indirect: addrlen); + assigns \result + \from (indirect: __fc_sockfds[sockfd]), (indirect: sockfd), + (indirect: addr), (indirect: *addr), (indirect: addrlen); */ -extern long double ceill(long double x); +extern int connect(int sockfd, struct sockaddr const *addr, socklen_t addrlen); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires valid_sockfd: 0 ≤ socket < 1024; + requires valid_address_len: \valid(address_len); + requires initialization: address_len: \initialized(address_len); + requires + valid_address: \valid((char *)address + (0 .. *address_len - 1)); + ensures new_address_len: *\old(address_len) ≤ \old(*address_len); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns *address_len, \result, + *((char *)address + (0 .. *address_len - 1)); + assigns *address_len \from (indirect: socket), __fc_sockfds[socket]; + assigns \result + \from (indirect: __fc_sockfds[socket]), (indirect: socket); + assigns *((char *)address + (0 .. *address_len - 1)) + \from (indirect: __fc_sockfds[socket]), (indirect: socket); */ -extern double floor(double x); +extern int getsockname(int socket, struct sockaddr * restrict address, + socklen_t * restrict address_len); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + requires valid_optlen: \valid(optlen); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns *((char *)optval + (0 ..)), \result, *optlen; + assigns *((char *)optval + (0 ..)) + \from (indirect: sockfd), (indirect: level), (indirect: optname), + (indirect: *optlen), (indirect: optval), + (indirect: __fc_sockfds[sockfd]); + assigns \result + \from (indirect: sockfd), (indirect: level), (indirect: optname), + (indirect: *optlen), (indirect: optval), + (indirect: __fc_sockfds[sockfd]); + assigns *optlen + \from (indirect: sockfd), (indirect: level), (indirect: optname), + *optlen, (indirect: optval), (indirect: __fc_sockfds[sockfd]); + + behavior so_error: + assumes optname_is_error: level ≡ 1 ∧ optname ≡ 4; + requires valid_optlen: \valid(optlen); + requires optlen_value: *optlen ≡ sizeof(int); + requires valid_optval: \valid((int *)optval); + assigns *((int *)optval), \result; + assigns *((int *)optval) + \from (indirect: sockfd), (indirect: optlen), + (indirect: __fc_sockfds[sockfd]); + assigns \result + \from (indirect: sockfd), (indirect: optlen), + (indirect: __fc_sockfds[sockfd]); + + behavior other_options: + assumes optname_not_error: ¬(level ≡ 1 ∧ optname ≡ 4); + requires + optval_null_or_valid: + optval ≡ \null ∨ \valid((char *)optval + (0 ..)); + assigns *((char *)optval + (0 ..)), \result, *optlen; + assigns *((char *)optval + (0 ..)) + \from (indirect: sockfd), (indirect: level), (indirect: optname), + (indirect: *optlen), (indirect: optval), + (indirect: __fc_sockfds[sockfd]); + assigns \result + \from (indirect: sockfd), (indirect: level), (indirect: optname), + (indirect: *optlen), (indirect: optval), + (indirect: __fc_sockfds[sockfd]); + assigns *optlen + \from (indirect: sockfd), (indirect: level), (indirect: optname), + *optlen, (indirect: optval), (indirect: __fc_sockfds[sockfd]); + + complete behaviors other_options, so_error; + disjoint behaviors other_options, so_error; */ -extern float floorf(float x); +extern int getsockopt(int sockfd, int level, int optname, void *optval, + socklen_t *optlen); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, __fc_sockfds[sockfd]; + assigns \result \from sockfd, __fc_sockfds[sockfd]; + assigns __fc_sockfds[sockfd] \from sockfd, backlog, __fc_sockfds[sockfd]; */ -extern long double floorl(long double x); +extern int listen(int sockfd, int backlog); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + requires valid_buffer_length: \valid((char *)buf + (0 .. len - 1)); + ensures + result_error_or_received_length: + \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len)); + ensures + initialization: \initialized((char *)\old(buf) + (0 .. \result - 1)); + assigns *((char *)buf + (0 .. len - 1)), __fc_sockfds[sockfd], \result; + assigns *((char *)buf + (0 .. len - 1)) + \from sockfd, len, flags, __fc_sockfds[sockfd]; + assigns __fc_sockfds[sockfd] + \from sockfd, len, flags, __fc_sockfds[sockfd]; + assigns \result \from sockfd, len, flags, __fc_sockfds[sockfd]; */ -extern double round(double x); +extern ssize_t recv(int sockfd, void *buf, size_t len, int flags); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; - */ -extern float roundf(float x); +ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, + struct sockaddr *addrbuf, socklen_t *addrbuf_len); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + requires + msg_control_has_room: + \valid((char *)hdr->msg_control + (0 .. hdr->msg_controllen - 1)); + requires + msg_iov_has_room: \valid(hdr->msg_iov + (0 .. hdr->msg_iovlen - 1)); + requires + msg_name_null_or_has_room: + hdr->msg_name ≡ \null ∨ + \valid((char *)hdr->msg_name + (0 .. hdr->msg_namelen - 1)); + ensures + result_error_or_received_length: + \result ≡ -1 ∨ (0 ≤ \result ≤ \old(hdr)->msg_iovlen); + assigns *((char *)hdr->msg_name + (0 .. hdr->msg_namelen - 1)), + hdr->msg_namelen, + *((char *)(hdr->msg_iov + (0 .. hdr->msg_iovlen - 1))->iov_base + + (0 ..)), + *((char *)hdr->msg_control + (0 .. hdr->msg_controllen - 1)), + \result, hdr->msg_controllen, hdr->msg_flags, + __fc_sockfds[sockfd]; + assigns *((char *)hdr->msg_name + (0 .. hdr->msg_namelen - 1)) + \from __fc_sockfds[sockfd]; + assigns hdr->msg_namelen \from __fc_sockfds[sockfd]; + assigns + *((char *)(hdr->msg_iov + (0 .. hdr->msg_iovlen - 1))->iov_base + (0 ..)) + \from __fc_sockfds[sockfd]; + assigns *((char *)hdr->msg_control + (0 .. hdr->msg_controllen - 1)) + \from __fc_sockfds[sockfd]; + assigns \result \from __fc_sockfds[sockfd]; + assigns hdr->msg_controllen \from __fc_sockfds[sockfd]; + assigns hdr->msg_flags \from __fc_sockfds[sockfd]; + assigns __fc_sockfds[sockfd] \from __fc_sockfds[sockfd]; */ -extern long double roundl(long double x); +extern ssize_t recvmsg(int sockfd, struct msghdr *hdr, int flags); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires available_sockfd: 0 ≤ sockfd < 1024; + requires buf_len_ok: \valid_read((char *)buf + (0 .. len - 1)); + ensures + error_or_chars_sent: \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len)); + assigns __fc_errno, __fc_sockfds[sockfd], \result; + assigns __fc_errno + \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), + (indirect: *((char *)buf + (0 .. len))), flags; + assigns __fc_sockfds[sockfd] + \from __fc_sockfds[sockfd], *((char *)buf + (0 .. len)), flags; + assigns \result + \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), + (indirect: *((char *)buf + (0 .. len))), (indirect: flags); */ -extern double trunc(double x); +extern ssize_t send(int sockfd, void const *buf, size_t len, int flags); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; +/*@ requires available_sockfd: 0 ≤ sockfd < 1024; + requires valid_message: \valid_read(message); + requires + valid_msg_iov: + \valid_read(message->msg_iov + (0 .. message->msg_iovlen - 1)); + ensures error_or_chars_sent: \result ≡ -1 ∨ 0 ≤ \result; + assigns __fc_sockfds[sockfd], \result; + assigns __fc_sockfds[sockfd] + \from __fc_sockfds[sockfd], (indirect: *message), + (indirect: *(message->msg_iov + (0 .. message->msg_iovlen - 1))), + (indirect: flags); + assigns \result + \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), + (indirect: *message), + (indirect: *(message->msg_iov + (0 .. message->msg_iovlen - 1))); */ -extern float truncf(float x); +extern ssize_t sendmsg(int sockfd, struct msghdr const *message, int flags); -/*@ requires finite_arg: \is_finite(x); - ensures finite_result: \is_finite(\result); - assigns \result; - assigns \result \from x; - */ -extern long double truncl(long double x); +ssize_t sendto(int sockfd, void const *buf, size_t len, int flags, + struct sockaddr const *address, socklen_t address_len); -/*@ requires in_domain: ¬\is_NaN(x) ∧ ¬\is_NaN(y) ∧ y ≢ 0.; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x, y; +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + requires + optval_null_or_has_room: + optval ≡ \null ∨ \valid_read((char *)optval + (0 .. optlen - 1)); + ensures result_error_or_ok: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, __fc_sockfds[sockfd]; + assigns \result + \from __fc_sockfds[sockfd], level, optname, + *((char *)optval + (0 .. optlen - 1)), optlen; + assigns __fc_sockfds[sockfd] + \from __fc_sockfds[sockfd], level, optname, + *((char *)optval + (0 .. optlen - 1)), optlen; */ -extern double fmod(double x, double y); +extern int setsockopt(int sockfd, int level, int optname, void const *optval, + socklen_t optlen); -/*@ requires in_domain: ¬\is_NaN(x) ∧ ¬\is_NaN(y) ∧ y ≢ 0.; - ensures finite_result: \is_finite(\result); - ensures no_error: __fc_errno ≡ \old(__fc_errno); - assigns \result; - assigns \result \from x, y; +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + ensures result_error_or_ok: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, __fc_sockfds[sockfd]; + assigns \result \from how, __fc_sockfds[sockfd]; + assigns __fc_sockfds[sockfd] \from how, __fc_sockfds[sockfd]; */ -extern float fmodf(float x, float y); +extern int shutdown(int sockfd, int how); -/*@ requires tagp_valid_string: valid_read_string(tagp); - ensures result_is_nan: \is_NaN(\result); - assigns \result; - assigns \result \from (indirect: *(tagp + (0 ..))); +/*@ ensures + result_error_or_valid_new_sockfd: + (0 ≤ \result < 1024) ∨ \result ≡ -1; + assigns \result, __fc_socket_counter; + assigns \result + \from (indirect: domain), (indirect: type), (indirect: protocol), + (indirect: __fc_socket_counter); + assigns __fc_socket_counter + \from (indirect: domain), (indirect: type), (indirect: protocol), + __fc_socket_counter; */ -extern double nan(char const *tagp); +extern int socket(int domain, int type, int protocol); -/*@ requires tagp_valid_string: valid_read_string(tagp); - ensures result_is_nan: \is_NaN(\result); - assigns \result; - assigns \result \from (indirect: *(tagp + (0 ..))); +/*@ requires valid_socket_sector: \valid(sv + (0 .. 1)); + ensures result_error_or_ok: \result ≡ 0 ∨ \result ≡ -1; + ensures initialization: sv: \initialized(\old(sv) + (0 .. 1)); + ensures valid_new_sockfd: sv0: 0 ≤ *(\old(sv) + 0) < 1024; + ensures valid_new_sockfd: sv1: 0 ≤ *(\old(sv) + 1) < 1024; + assigns \result, __fc_socket_counter, *(sv + (0 .. 1)); + assigns \result \from __fc_socket_counter; + assigns __fc_socket_counter \from __fc_socket_counter; + assigns *(sv + (0 .. 1)) \from __fc_socket_counter; */ -extern float nanf(char const *tagp); +extern int socketpair(int domain, int type, int protocol, int sv[2]); -/*@ requires tagp_valid_string: valid_read_string(tagp); - ensures result_is_nan: \is_NaN(\result); - assigns \result; - assigns \result \from (indirect: *(tagp + (0 ..))); - */ -extern long double nanl(char const *tagp); +struct in6_addr const in6addr_any; -int __finitef(float f); +struct in6_addr const in6addr_loopback; -int __finite(double d); +/*@ assigns \result; + assigns \result \from arg; */ +extern uint32_t htonl(uint32_t arg); -/*@ logic float __fc_infinity(ℤ x) = \plus_infinity; - */ -/*@ logic float __fc_nan(ℤ x) = \NaN; +/*@ assigns \result; + assigns \result \from arg; */ +extern uint16_t htons(uint16_t arg); -*/ -/*@ ensures result_is_infinity: \is_plus_infinity(\result); +/*@ assigns \result; + assigns \result \from arg; */ +extern uint32_t ntohl(uint32_t arg); + +/*@ assigns \result; + assigns \result \from arg; */ +extern uint16_t ntohs(uint16_t arg); + +/*@ requires valid_arg: valid_read_string(arg); assigns \result; - assigns \result \from \nothing; + assigns \result \from (indirect: *(arg + (0 ..))); */ -extern float __fc_infinity(int x); +extern in_addr_t inet_addr(char const *arg); -/*@ ensures result_is_nan: \is_NaN(\result); - assigns \result; - assigns \result \from \nothing; +char volatile __fc_inet_ntoa_array[16]; +char *__fc_inet_ntoa = (char *)(__fc_inet_ntoa_array); +/*@ ensures result_static_string: \result ≡ __fc_inet_ntoa; + ensures result_null_terminated: *(\result + 15) ≡ 0; + ensures result_valid_string: valid_read_string(\result); + assigns \result, *(__fc_inet_ntoa + (0 ..)); + assigns \result \from (indirect: arg), __fc_inet_ntoa; + assigns *(__fc_inet_ntoa + (0 ..)) \from (indirect: arg); */ -extern float __fc_nan(int x); +extern char *inet_ntoa(struct in_addr arg); -/*@ requires finite_arg: \is_finite(x); - ensures res_finite: \is_finite(\result); - ensures positive_result: \result ≥ 0.; - ensures - equal_magnitude_result: \result ≡ \old(x) ∨ \result ≡ -\old(x); - assigns \result; - assigns \result \from x; +/*@ assigns \result, *(dst + (0 .. size - 1)); + assigns \result \from dst, af, *((char *)src + (0 ..)); + assigns *(dst + (0 .. size - 1)) \from af, *((char *)src + (0 ..)); */ -double fabs(double x) -{ - double __retres; - if (x == 0.0) { - __retres = 0.0; - goto return_label; - } - if (x > 0.0) { - __retres = x; - goto return_label; - } - __retres = - x; - return_label: return __retres; -} +extern char const *inet_ntop(int af, void const *src, char *dst, + socklen_t size); -/*@ requires finite_arg: \is_finite(x); - ensures res_finite: \is_finite(\result); - ensures positive_result: \result ≥ 0.; - ensures - equal_magnitude_result: \result ≡ \old(x) ∨ \result ≡ -\old(x); - assigns \result; - assigns \result \from x; +/*@ assigns \result, *((char *)dst + (0 ..)); + assigns \result \from af, *(src + (..)); + assigns *((char *)dst + (0 ..)) \from af, *(src + (0 ..)); */ -float fabsf(float x) -{ - float __retres; - if (x == 0.0f) { - __retres = 0.0f; - goto return_label; - } - else - if (x > 0.0f) { - __retres = x; - goto return_label; - } - else { - __retres = - x; - goto return_label; - } - return_label: return __retres; -} +extern int inet_pton(int af, char const *src, void *dst); -/*@ assigns \result; - assigns \result \from f; - - behavior finite: - assumes isfinite_f: \is_finite(f); - ensures nonzero_result: \result > 0 ∨ \result < 0; - - behavior nonfinite: - assumes nonfinite_f: ¬\is_finite(f); - ensures zero_result: \result ≡ 0; - - complete behaviors nonfinite, finite; - disjoint behaviors nonfinite, finite; +int h_errno; +/*@ requires addrinfo_valid: \valid(addrinfo); + ensures allocation: \allocable(\old(addrinfo)); + assigns \nothing; + frees addrinfo; */ -int __finitef(float f) -{ - int __retres; - union __fc_u_finitef u; - unsigned short usExp; - u.f = f; - usExp = (unsigned short)((int)u.w[1] & 0x7F80); - usExp = (unsigned short)((int)usExp >> 7); - __retres = ! ((int)usExp == 0xff); - return __retres; -} +extern void freeaddrinfo(struct addrinfo *addrinfo); -/*@ assigns \result; - assigns \result \from d; +char const *__fc_gai_strerror = "<error message reported by gai_strerror>"; +/*@ ensures result_string: \result ≡ __fc_gai_strerror; + ensures result_valid_string: valid_read_string(\result); + assigns \result; + assigns \result \from (indirect: errcode), __fc_gai_strerror; + */ +extern char const *gai_strerror(int errcode); + +int getaddrinfo(char const * restrict nodename, + char const * restrict servname, + struct addrinfo const * restrict hints, + struct addrinfo ** restrict res); + +struct hostent *gethostbyname(char const *name); + +static unsigned int volatile getaddrinfo_net_state; +/*@ requires + nodename_string: nodename ≡ \null ∨ valid_read_string(nodename); + requires + servname_string: servname ≡ \null ∨ valid_read_string(servname); + requires hints_option: hints ≡ \null ∨ \valid_read(hints); + requires valid_res: \valid(res); + assigns *res, \result, __fc_errno; + assigns *res + \from (indirect: nodename), (indirect: servname), (indirect: hints); + assigns \result + \from (indirect: nodename), (indirect: servname), (indirect: hints); + assigns __fc_errno + \from (indirect: nodename), (indirect: servname), (indirect: hints); + allocates *\old(res); - behavior finite: - assumes isfinite_d: \is_finite(d); - ensures nonzero_result: \result > 0 ∨ \result < 0; + behavior empty_request: + assumes empty: nodename ≡ \null ∧ servname ≡ \null; + ensures no_name: \result ≡ -2; + assigns \result; + assigns \result \from (indirect: nodename), (indirect: servname); - behavior nonfinite: - assumes nonfinite_d: ¬\is_finite(d); - ensures zero_result: \result ≡ 0; + behavior normal_request: + assumes has_name: nodename ≢ \null ∨ servname ≢ \null; + ensures + initialization: allocation: success_or_error: + (\result ≡ 0 ∧ + \fresh{Old, Here}(*\old(res),sizeof(*\old(res))) ∧ + \initialized(*\old(res))) ∨ + \result ≡ -3 ∨ \result ≡ -1 ∨ \result ≡ -4 ∨ + \result ≡ -6 ∨ \result ≡ -10 ∨ \result ≡ -8 ∨ + \result ≡ -7 ∨ \result ≡ -11; - complete behaviors nonfinite, finite; - disjoint behaviors nonfinite, finite; + complete behaviors normal_request, empty_request; + disjoint behaviors normal_request, empty_request; */ -int __finite(double d) +int getaddrinfo(char const * restrict nodename, + char const * restrict servname, + struct addrinfo const * restrict hints, + struct addrinfo ** restrict res) { int __retres; - union __fc_u_finite u; - unsigned short usExp; - u.d = d; - usExp = (unsigned short)((int)u.w[3] & 0x7F80); - usExp = (unsigned short)((int)usExp >> 7); - __retres = ! ((int)usExp == 0xff); - return __retres; + if (nodename == (char const *)0) + if (servname == (char const *)0) { + __retres = -2; + goto return_label; + } + switch (getaddrinfo_net_state) { + case (unsigned int)0: __retres = -1; + goto return_label; + case (unsigned int)1: __retres = -3; + goto return_label; + case (unsigned int)2: __retres = -4; + goto return_label; + case (unsigned int)3: __retres = -6; + goto return_label; + case (unsigned int)5: __retres = -8; + goto return_label; + case (unsigned int)6: __retres = -7; + goto return_label; + case (unsigned int)7: + { + __fc_errno = 5; + __retres = -11; + goto return_label; + } + default: + { + struct addrinfo *tmp_0; + struct sockaddr *tmp_2; + int tmp_3; + struct addrinfo *ai = malloc(sizeof(*tmp_0)); + if (! ai) { + __retres = -10; + goto return_label; + } + struct sockaddr *sa = malloc(sizeof(*tmp_2)); + if (! sa) { + __retres = -10; + goto return_label; + } + tmp_3 = Frama_C_interval(0,43); + sa->sa_family = (sa_family_t)tmp_3; + /*@ slevel 15; */ + { + int i = 0; + while (i < 14) { + { + int tmp_4; + tmp_4 = Frama_C_interval(-128,127); + sa->sa_data[i] = (char)tmp_4; + } + i ++; + } + } + /*@ slevel default; */ + ai->ai_flags = 0; + ai->ai_family = (int)sa->sa_family; + ai->ai_socktype = Frama_C_interval(0,5); + ai->ai_protocol = Frama_C_interval(0,IPPROTO_MAX); + ai->ai_addrlen = sizeof(*sa); + ai->ai_addr = sa; + ai->ai_canonname = (char *)malloc((size_t)6); + if (! ai->ai_canonname) { + __retres = -10; + goto return_label; + } + strcpy(ai->ai_canonname,"dummy"); + ai->ai_next = (struct addrinfo *)0; + *res = ai; + __retres = 0; + goto return_label; + } + } + return_label: return __retres; } -/*@ assigns \nothing; */ -extern void (*signal(int sig, void (*func)(int )))(int ); +struct __fc_gethostbyname __fc_ghbn; +static int res_search(char const *dname, int rec_class, int type, + char *answer, int anslen) +{ + int tmp; + { + int i = 0; + while (i < anslen - 1) { + *(answer + i) = Frama_C_char_interval((char)(-128),(char)127); + i ++; + } + } + *(answer + (anslen - 1)) = (char)0; + tmp = Frama_C_interval(-1,anslen); + return tmp; +} -/*@ ensures never_terminates: \false; - assigns \nothing; */ -extern int raise(int sig); +struct hostent *gethostbyname(char const *name) +{ + struct hostent *__retres; + char buf[128]; + char const *cp; + int n; + int tmp; + __fc_ghbn.host.h_addrtype = 2; + __fc_ghbn.host.h_length = (int)sizeof(struct in_addr); + if ((int)*name >= '0') + if ((int)*name <= '9') { + cp = name; + while (1) { + if (! *cp) { + struct in_addr addr; + cp --; + ; + if ((int)*cp == '.') break; + addr.s_addr = inet_addr(name); + if (addr.s_addr == 0xffffffff) { + __retres = (struct hostent *)0; + goto return_label; + } + memcpy((void *)(__fc_ghbn.host_addr),(void const *)(& addr), + (size_t)__fc_ghbn.host.h_length); + strncpy(__fc_ghbn.hostbuf,name,(size_t)(128 - 1)); + __fc_ghbn.hostbuf[128 - 1] = (char)'\000'; + __fc_ghbn.host.h_name = __fc_ghbn.hostbuf; + __fc_ghbn.host.h_aliases = __fc_ghbn.host_aliases; + __fc_ghbn.host_aliases[0] = (char *)0; + __fc_ghbn.h_addr_ptrs[0] = (char *)(__fc_ghbn.host_addr); + __fc_ghbn.h_addr_ptrs[1] = (char *)0; + __fc_ghbn.host.h_addr_list = __fc_ghbn.h_addr_ptrs; + __retres = & __fc_ghbn.host; + goto return_label; + } + if ((int)*cp < '0') break; + else + if ((int)*cp > '9') break; + else + if ((int)*cp != '.') break; + cp ++; + } + } + n = res_search(name,1,1,buf,(int)sizeof(buf)); + if (n < 0) { + __retres = (struct hostent *)0; + goto return_label; + } + tmp = Frama_C_nondet(0,1); + if (tmp) { + __retres = (struct hostent *)0; + goto return_label; + } + else { + struct in_addr addr_0; + addr_0.s_addr = inet_addr(name); + memcpy((void *)(__fc_ghbn.host_addr),(void const *)(& addr_0), + (size_t)__fc_ghbn.host.h_length); + strncpy(__fc_ghbn.hostbuf,name,(size_t)(128 - 1)); + __fc_ghbn.hostbuf[128 - 1] = (char)'\000'; + __fc_ghbn.host.h_name = __fc_ghbn.hostbuf; + __fc_ghbn.host.h_aliases = __fc_ghbn.host_aliases; + __fc_ghbn.host_aliases[0] = (char *)0; + __fc_ghbn.h_addr_ptrs[0] = (char *)(__fc_ghbn.host_addr); + __fc_ghbn.h_addr_ptrs[1] = (char *)0; + __fc_ghbn.host.h_addr_list = __fc_ghbn.h_addr_ptrs; + __retres = & __fc_ghbn.host; + goto return_label; + } + return_label: return __retres; +} -/*@ requires valid_set: \valid(set); - ensures initialization: set: \initialized(\old(set)); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns *set, \result; - assigns *set \from \nothing; - assigns \result \from \nothing; +struct in6_addr const in6addr_any = {.s6_addr = {(uint8_t)0}}; +struct in6_addr const in6addr_loopback = + {.s6_addr = {(uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)0, + (uint8_t)1}}; +char __fc_getpw_pw_name[64]; +char __fc_getpw_pw_passwd[64]; +char __fc_getpw_pw_gecos[64]; +char __fc_getpw_pw_dir[64]; +char __fc_getpw_pw_shell[64]; +struct passwd __fc_pwd = + {.pw_name = __fc_getpw_pw_name, + .pw_passwd = __fc_getpw_pw_passwd, + .pw_uid = 0U, + .pw_gid = 0U, + .pw_gecos = __fc_getpw_pw_gecos, + .pw_dir = __fc_getpw_pw_dir, + .pw_shell = __fc_getpw_pw_shell}; +struct passwd *__fc_p_pwd = & __fc_pwd; +/*@ requires valid_name: valid_read_string(name); + ensures + result_null_or_internal_struct: + \result ≡ \null ∨ \result ≡ __fc_p_pwd; + assigns \result, __fc_pwd; + assigns \result \from __fc_p_pwd, (indirect: *(name + (0 ..))); + assigns __fc_pwd \from (indirect: *(name + (0 ..))); */ -extern int sigemptyset(sigset_t *set); +extern struct passwd *getpwnam(char const *name); -/*@ requires valid_set: \valid(set); - ensures initialization: set: \initialized(\old(set)); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns *set, \result; - assigns *set \from \nothing; - assigns \result \from \nothing; +/*@ ensures + result_null_or_internal_struct: + \result ≡ \null ∨ \result ≡ __fc_p_pwd; + assigns \result, __fc_pwd; + assigns \result \from __fc_p_pwd, (indirect: uid); + assigns __fc_pwd \from (indirect: uid); */ -extern int sigfillset(sigset_t *set); +extern struct passwd *getpwuid(uid_t uid); -/*@ requires valid_set: \valid(set); - requires initialization: set: \initialized(set); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns *set, \result; - assigns *set \from (indirect: signum); - assigns \result \from signum; - */ -extern int sigaddset(sigset_t *set, int signum); +int getpwnam_r(char const *name, struct passwd *pwd, char *buf, + size_t buflen, struct passwd **result); -/*@ requires valid_set: \valid(set); - requires initialization: set: \initialized(set); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns *set, \result; - assigns *set \from (indirect: signum); - assigns \result \from signum; - */ -extern int sigdelset(sigset_t *set, int signum); +int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, + struct passwd **result); -/*@ requires valid_read_set: \valid_read(set); - requires initialization: set: \initialized(set); - ensures - result_found_not_found_or_error: - \result ≡ 0 ∨ \result ≡ 1 ∨ \result ≡ -1; - assigns \result; - assigns \result \from *set, signum; - */ -extern int sigismember(sigset_t const *set, int signum); +static int __fc_getpw_init; +static int __fc_getpw_r(struct passwd *pwd, char *buf, size_t buflen, + struct passwd **result) +{ + int __retres; + int tmp_2; + if (! __fc_getpw_init) { + __fc_getpw_init = 1; + Frama_C_make_unknown(__fc_getpw_pw_name,(size_t)63); + __fc_getpw_pw_name[63] = (char)0; + Frama_C_make_unknown(__fc_getpw_pw_passwd,(size_t)63); + __fc_getpw_pw_passwd[63] = (char)0; + Frama_C_make_unknown(__fc_getpw_pw_gecos,(size_t)63); + __fc_getpw_pw_gecos[63] = (char)0; + Frama_C_make_unknown(__fc_getpw_pw_dir,(size_t)63); + __fc_getpw_pw_dir[63] = (char)0; + Frama_C_make_unknown(__fc_getpw_pw_shell,(size_t)63); + __fc_getpw_pw_shell[63] = (char)0; + } + tmp_2 = Frama_C_interval(0,1); + if (tmp_2) { + int tmp; + int tmp_0; + int tmp_1; + *result = (struct passwd *)0; + tmp = Frama_C_interval(0,1); + if (tmp) { + __retres = 5; + goto return_label; + } + tmp_0 = Frama_C_interval(0,1); + if (tmp_0) { + __retres = 24; + goto return_label; + } + tmp_1 = Frama_C_interval(0,1); + if (tmp_1) { + __retres = 23; + goto return_label; + } + __retres = 0; + goto return_label; + } + else { + size_t len; + size_t remaining = buflen; + len = strlen((char const *)__fc_pwd.pw_name); + if (remaining <= len) { + *result = (struct passwd *)0; + __retres = 34; + goto return_label; + } + strcpy(buf,(char const *)__fc_pwd.pw_name); + *(buf + len) = (char)0; + pwd->pw_name = buf; + buf += len + (size_t)1; + remaining -= len; + len = strlen((char const *)__fc_pwd.pw_passwd); + if (remaining <= len) { + *result = (struct passwd *)0; + __retres = 34; + goto return_label; + } + strcpy(buf,(char const *)__fc_pwd.pw_passwd); + *(buf + len) = (char)0; + pwd->pw_passwd = buf; + buf += len + (size_t)1; + remaining -= len; + len = strlen((char const *)__fc_pwd.pw_gecos); + if (remaining <= len) { + *result = (struct passwd *)0; + __retres = 34; + goto return_label; + } + strcpy(buf,(char const *)__fc_pwd.pw_gecos); + *(buf + len) = (char)0; + pwd->pw_gecos = buf; + buf += len + (size_t)1; + remaining -= len; + len = strlen((char const *)__fc_pwd.pw_dir); + if (remaining <= len) { + *result = (struct passwd *)0; + __retres = 34; + goto return_label; + } + strcpy(buf,(char const *)__fc_pwd.pw_dir); + *(buf + len) = (char)0; + pwd->pw_dir = buf; + buf += len + (size_t)1; + remaining -= len; + len = strlen((char const *)__fc_pwd.pw_shell); + if (remaining <= len) { + *result = (struct passwd *)0; + __retres = 34; + goto return_label; + } + strcpy(buf,(char const *)__fc_pwd.pw_shell); + *(buf + len) = (char)0; + pwd->pw_shell = buf; + buf += len + (size_t)1; + remaining -= len; + pwd->pw_uid = Frama_C_unsigned_int_interval((unsigned int)0,4294967295U); + pwd->pw_gid = Frama_C_unsigned_int_interval((unsigned int)0,4294967295U); + *result = pwd; + __retres = 0; + goto return_label; + } + return_label: return __retres; +} -struct sigaction __fc_sigaction[64 + 1]; -struct sigaction *__fc_p_sigaction = __fc_sigaction; -/*@ requires valid_signal: 0 ≤ signum ≤ 64; - requires valid_oldact_or_null: oldact ≡ \null ∨ \valid(oldact); - requires valid_read_act_or_null: act ≡ \null ∨ \valid_read(act); - requires separation: separated_acts: \separated(act, oldact); +/*@ requires valid_name: valid_read_string(name); + requires valid_buf: \valid(buf + (0 .. buflen - 1)); + requires valid_pwd: \valid(pwd); + requires valid_result: \valid(result); ensures - act_changed: - \old(act) ≡ \null ∨ - \subset(*(__fc_p_sigaction + \old(signum)), *\old(act)); + result_null_or_assigned: + *\old(result) ≡ \null ∨ *\old(result) ≡ \old(pwd); ensures - oldact_assigned: - \old(oldact) ≡ \null ∨ - *\old(oldact) ∈ *(__fc_p_sigaction + \old(signum)); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns *oldact, *(__fc_p_sigaction + signum), \result; - assigns *oldact \from __fc_p_sigaction; - assigns *(__fc_p_sigaction + signum) \from *act; + result_ok_or_error: \result ≡ 0 ∨ \result ∈ {5, 24, 23, 34}; + assigns \result, __fc_pwd, *pwd, *result, *(buf + (0 .. buflen - 1)); assigns \result - \from (indirect: signum), (indirect: act), (indirect: *act), - (indirect: oldact), (indirect: *oldact); + \from (indirect: __fc_p_pwd), (indirect: *(name + (0 ..))); + assigns __fc_pwd \from (indirect: *(name + (0 ..))); + assigns *pwd \from __fc_p_pwd; + assigns *result \from __fc_p_pwd; + assigns *(buf + (0 .. buflen - 1)) \from (indirect: *__fc_p_pwd); */ -extern int sigaction(int signum, struct sigaction const * restrict act, - struct sigaction * restrict oldact); +int getpwnam_r(char const *name, struct passwd *pwd, char *buf, + size_t buflen, struct passwd **result) +{ + int tmp; + /*@ assert valid_read_string(name); */ ; + tmp = __fc_getpw_r(pwd,buf,buflen,result); + return tmp; +} -/*@ requires valid_set_or_null: set ≡ \null ∨ \valid_read(set); - requires valid_how: set ≢ \null ⇒ how ∈ {0, 2, 1}; - requires valid_oldset_or_null: oldset ≡ \null ∨ \valid(oldset); - requires - separation: (set ≡ oldset ≡ \null) ∨ \separated(set, oldset); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires valid_buf: \valid(buf + (0 .. buflen - 1)); + requires valid_pwd: \valid(pwd); + requires valid_result: \valid(result); ensures - initialization: oldset_initialized: - \old(oldset) ≢ \null ∧ \result ≡ 0 ⇒ - \initialized(\old(oldset)); - assigns \result, *oldset; - assigns \result - \from (indirect: how), (indirect: set), (indirect: oldset); - assigns *oldset \from (indirect: how), (indirect: oldset); - */ -extern int sigprocmask(int how, sigset_t const * restrict set, - sigset_t * restrict oldset); - -/*@ requires valid_mask_or_null: sigmask ≡ \null ∨ \valid_read(sigmask); - ensures result_means_interrupted: \result ≡ -1; - ensures errno_set: __fc_errno ≡ 4; - assigns __fc_errno, \result; - assigns __fc_errno \from (indirect: sigmask); - assigns \result \from (indirect: sigmask); - */ -extern int sigsuspend(sigset_t const *sigmask); - -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result \from (indirect: pid), (indirect: sig); - */ -extern int kill(pid_t pid, int sig); - -/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result; - assigns \result \from (indirect: pgrp), (indirect: sig); + result_null_or_assigned: + *\old(result) ≡ \null ∨ *\old(result) ≡ \old(pwd); + ensures + result_ok_or_error: \result ≡ 0 ∨ \result ∈ {5, 24, 23, 34}; + assigns \result, __fc_pwd, *pwd, *result, *(buf + (0 .. buflen - 1)); + assigns \result \from (indirect: __fc_p_pwd); + assigns __fc_pwd \from (indirect: uid); + assigns *pwd \from __fc_p_pwd; + assigns *result \from __fc_p_pwd; + assigns *(buf + (0 .. buflen - 1)) \from (indirect: *__fc_p_pwd); */ -extern int killpg(pid_t pgrp, int sig); +int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, + struct passwd **result) +{ + int tmp; + tmp = __fc_getpw_r(pwd,buf,buflen,result); + return tmp; +} -/*@ requires valid_fd: 0 ≤ fd < 1024; - requires - initialization: initialized_inputs: - ∀ ℤ i; - 0 ≤ i < iovcnt ⇒ - \initialized(&(iov + i)->iov_base) ∧ - \initialized(&(iov + i)->iov_len); - requires - valid_iov: - ∀ ℤ i; - 0 ≤ i < iovcnt ⇒ - \valid((char *)(&(iov + i)->iov_base) + - (0 .. (iov + i)->iov_len - 1)); - requires bounded_iovcnt: 0 ≤ iovcnt ≤ 1024; +/*@ requires available_sockfd: 0 ≤ sockfd < 1024; + requires buf_len_ok: \valid_read((char *)buf + (0 .. len - 1)); ensures - result_error_or_read_bytes: - \result ≡ -1 ∨ - (0 ≤ \result ≤ - \sum(0, \old(iovcnt) - 1, \lambda ℤ k; (\old(iov) + k)->iov_len)); - assigns {*((char *)(iov + i)->iov_base + j) | - ℤ i, ℤ j; 0 ≤ i < iovcnt ∧ 0 ≤ j < (iov + i)->iov_len}, - \result; - assigns - {*((char *)(iov + i)->iov_base + j) | - ℤ i, ℤ j; 0 ≤ i < iovcnt ∧ 0 ≤ j < (iov + i)->iov_len} - \from (indirect: fd), (indirect: iovcnt), (indirect: __fc_fds[fd]); + error_or_chars_sent: \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len)); + assigns __fc_errno, __fc_sockfds[sockfd], \result; + assigns __fc_errno + \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), + (indirect: *((char *)buf + (0 .. len))), flags; + assigns __fc_sockfds[sockfd] + \from __fc_sockfds[sockfd], *((char *)buf + (0 .. len)), flags; assigns \result - \from (indirect: fd), (indirect: __fc_fds[fd]), - (indirect: *(iov + (0 ..))), (indirect: iovcnt); + \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), + (indirect: *((char *)buf + (0 .. len))), (indirect: flags); */ -extern ssize_t readv(int fd, struct iovec const *iov, int iovcnt); +ssize_t sendto(int sockfd, void const *buf, size_t len, int flags, + struct sockaddr const *address, socklen_t address_len) +{ + ssize_t __retres; + int tmp_1; + tmp_1 = Frama_C_nondet(0,1); + if (tmp_1) { + int tmp; + int possible_errors[25] = + {13, + 97, + 11, + 9, + 104, + 89, + 113, + 4, + 22, + 5, + 106, + 40, + 90, + 36, + 100, + 101, + 105, + 2, + 12, + 107, + 20, + 88, + 95, + 32, + 11}; + tmp = Frama_C_interval(0, + (int)(sizeof(possible_errors) / sizeof(int) - (unsigned int)1)); + __fc_errno = possible_errors[tmp]; + __retres = -1; + goto return_label; + } + else { + ssize_t tmp_0; + tmp_0 = (ssize_t)Frama_C_long_interval((long)0,(long)len); + __retres = tmp_0; + goto return_label; + } + return_label: return __retres; +} -/*@ requires valid_fd: 0 ≤ fd < 1024; - requires - initialization: initialized_inputs: - ∀ ℤ i; - 0 ≤ i < iovcnt ⇒ - \initialized(&(iov + i)->iov_base) ∧ - \initialized(&(iov + i)->iov_len); - requires valid_read_iov: \valid_read(iov + (0 .. iovcnt - 1)); - requires - valid_read_iov_bases: - ∀ ℤ i; - 0 ≤ i < iovcnt ⇒ - \valid_read((char *)(iov + i)->iov_base + - (0 .. (iov + i)->iov_len - 1)); - requires bounded_iovcnt: 0 ≤ iovcnt ≤ 1024; +/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; + requires valid_buffer_length: \valid((char *)buf + (0 .. len - 1)); requires - bounded_lengths: - \sum(0, iovcnt - 1, \lambda ℤ k; (iov + k)->iov_len) ≤ 2147483647; + valid_addrbuf_or_null: initialization: + (\valid(addrbuf_len) ∧ \initialized(addrbuf_len) ∧ + \valid((char *)addrbuf + (0 .. *addrbuf_len - 1))) ∨ + (addrbuf ≡ \null ∧ addrbuf_len ≡ \null); ensures - result_error_or_written_bytes: - \result ≡ -1 ∨ - (0 ≤ \result ≤ - \sum(0, \old(iovcnt) - 1, \lambda ℤ k; (\old(iov) + k)->iov_len)); - assigns \result, __fc_fds[fd]; - assigns \result - \from (indirect: fd), (indirect: __fc_fds[fd]), - (indirect: *(iov + (0 ..))), (indirect: iovcnt); - assigns __fc_fds[fd] - \from (indirect: *(iov + (0 ..))), (indirect: iovcnt); + result_error_or_received_length: + \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len)); + ensures + initialization: buf: + \initialized((char *)\old(buf) + (0 .. \result - 1)); + ensures + initialization: addrbuf: + \old(addrbuf) ≢ \null ⇒ + \initialized((char *)\old(addrbuf) + (0 .. \old(*addrbuf_len) - 1)); + assigns *((char *)buf + (0 .. len - 1)), __fc_sockfds[sockfd], \result, + *addrbuf_len, *((char *)addrbuf + (0 .. \old(*addrbuf_len) - 1)); + assigns *((char *)buf + (0 .. len - 1)) + \from sockfd, len, flags, __fc_sockfds[sockfd]; + assigns __fc_sockfds[sockfd] + \from sockfd, len, flags, __fc_sockfds[sockfd]; + assigns \result \from sockfd, len, flags, __fc_sockfds[sockfd]; + assigns *addrbuf_len + \from (indirect: sockfd), (indirect: len), (indirect: flags), + __fc_sockfds[sockfd]; + assigns *((char *)addrbuf + (0 .. \old(*addrbuf_len) - 1)) + \from (indirect: sockfd), (indirect: len), (indirect: flags), + __fc_sockfds[sockfd]; */ -extern ssize_t writev(int fd, struct iovec const *iov, int iovcnt); +ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, + struct sockaddr *addrbuf, socklen_t *addrbuf_len) +{ + ssize_t __retres; + int tmp_3; + tmp_3 = Frama_C_nondet(0,1); + if (tmp_3) { + int tmp; + int possible_errors[13] = + {11, 9, 104, 4, 22, 5, 105, 12, 107, 88, 95, 110, 11}; + tmp = Frama_C_interval(0, + (int)(sizeof(possible_errors) / sizeof(int) - (unsigned int)1)); + __fc_errno = possible_errors[tmp]; + __retres = -1; + goto return_label; + } + else { + int tmp_0; + int tmp_1; + ssize_t tmp_2; + tmp_0 = Frama_C_interval(0,(int)(len - (size_t)1)); + tmp_1 = Frama_C_interval(0,255); + *((char *)buf + tmp_0) = (char)tmp_1; + if (addrbuf) { + Frama_C_make_unknown((char *)addrbuf,*addrbuf_len); + *addrbuf_len = Frama_C_unsigned_int_interval((unsigned int)0, + (unsigned int)128); + } + tmp_2 = (ssize_t)Frama_C_long_interval((long)0,(long)len); + __retres = tmp_2; + goto return_label; + } + return_label: return __retres; +} -/*@ ghost struct __fc_sockfds_type __fc_sockfds[1024]; */ -/*@ ghost extern int __fc_socket_counter; */ +/*@ ghost unsigned int volatile __fc_time; */ +/*@ assigns \result; + assigns \result \from __fc_time; */ +extern clock_t clock(void); -/*@ ghost int volatile __fc_open_sock_fds; */ -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - ensures - result_error_or_valid_new_sockfd: - \result ≡ -1 ∨ (0 ≤ \result < 1024); - assigns \result, *((char *)addr + (0 .. *addrlen - 1)), - __fc_sockfds[sockfd]; - assigns \result \from *addr, *addrlen, __fc_sockfds[sockfd]; - assigns *((char *)addr + (0 .. *addrlen - 1)) - \from *addr, *addrlen, __fc_sockfds[sockfd]; - assigns __fc_sockfds[sockfd] \from *addr, *addrlen, __fc_sockfds[sockfd]; +/*@ assigns \result; + assigns \result \from time1, time0; */ +extern double difftime(time_t time1, time_t time0); + +/*@ requires valid_timeptr: \valid(timeptr); + assigns *timeptr, \result; + assigns *timeptr \from *timeptr; + assigns \result \from (indirect: *timeptr); + */ +extern time_t mktime(struct tm *timeptr); + +/*@ assigns *timer, \result; + assigns *timer \from __fc_time; + assigns \result \from __fc_time; - behavior addr_null: - assumes addr_is_null: addr ≡ \null; - requires addrlen_should_be_null: addrlen ≡ \null; - assigns \result, __fc_sockfds[sockfd]; - assigns \result \from __fc_sockfds[sockfd]; - assigns __fc_sockfds[sockfd] \from __fc_sockfds[sockfd]; + behavior null: + assumes timer_null: timer ≡ \null; + assigns \result; + assigns \result \from __fc_time; - behavior addr_not_null: - assumes addr_is_not_null: addr ≢ \null; - requires valid_addrlen: \valid(addrlen); - requires addr_has_room: \valid((char *)addr + (0 .. *addrlen - 1)); - ensures - initialization: addr: - \initialized((char *)\old(addr) + (0 .. *\old(addrlen) - 1)); + behavior not_null: + assumes timer_non_null: timer ≢ \null; + requires valid_timer: \valid(timer); + ensures initialization: timer: \initialized(\old(timer)); + assigns *timer, \result; + assigns *timer \from __fc_time; + assigns \result \from __fc_time; - disjoint behaviors addr_not_null, addr_null; + complete behaviors not_null, null; + disjoint behaviors not_null, null; */ -extern int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); +extern time_t time(time_t *timer); -/*@ requires valid_sockfd: sockfd: 0 ≤ sockfd < 1024; - requires valid_read_addr: \valid_read((char *)addr + (0 .. addrlen - 1)); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns __fc_sockfds[sockfd], \result; - assigns __fc_sockfds[sockfd] - \from sockfd, *addr, addrlen, __fc_sockfds[sockfd]; +char __fc_ctime[26]; +char * const __fc_p_ctime = __fc_ctime; +/*@ requires valid_timeptr: \valid_read(timeptr); + requires initialization: init_timeptr: \initialized(timeptr); + ensures result_points_to_ctime: \result ≡ __fc_p_ctime; + ensures result_valid_string: valid_read_string(__fc_p_ctime); + assigns __fc_ctime[0 .. 25], \result; + assigns __fc_ctime[0 .. 25] + \from (indirect: *timeptr), (indirect: __fc_time); assigns \result - \from (indirect: sockfd), (indirect: *addr), (indirect: addrlen), - (indirect: __fc_sockfds[sockfd]); + \from (indirect: *timeptr), (indirect: __fc_time), __fc_p_ctime; */ -extern int bind(int sockfd, struct sockaddr const *addr, socklen_t addrlen); +extern char *asctime(struct tm const *timeptr); -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - requires valid_read_addr: \valid_read((char *)addr + (0 .. addrlen - 1)); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns __fc_sockfds[sockfd], \result; - assigns __fc_sockfds[sockfd] - \from __fc_sockfds[sockfd], (indirect: sockfd), (indirect: addr), - (indirect: *addr), (indirect: addrlen); - assigns \result - \from (indirect: __fc_sockfds[sockfd]), (indirect: sockfd), - (indirect: addr), (indirect: *addr), (indirect: addrlen); +/*@ requires valid_timer: \valid_read(timer); + requires initialization: init_timer: \initialized(timer); + ensures result_points_to_ctime: \result ≡ __fc_p_ctime; + ensures result_valid_string: valid_read_string(__fc_p_ctime); + assigns __fc_ctime[0 .. 25], \result; + assigns __fc_ctime[0 .. 25] + \from (indirect: *timer), (indirect: __fc_time); + assigns \result + \from (indirect: *timer), (indirect: __fc_time), __fc_p_ctime; */ -extern int connect(int sockfd, struct sockaddr const *addr, socklen_t addrlen); +extern char *ctime(time_t const *timer); -/*@ requires valid_sockfd: 0 ≤ socket < 1024; - requires valid_address_len: \valid(address_len); - requires initialization: address_len: \initialized(address_len); - requires - valid_address: \valid((char *)address + (0 .. *address_len - 1)); - ensures new_address_len: *\old(address_len) ≤ \old(*address_len); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns *address_len, \result, - *((char *)address + (0 .. *address_len - 1)); - assigns *address_len \from (indirect: socket), __fc_sockfds[socket]; +struct tm __fc_time_tm; +struct tm * const __fc_p_time_tm = & __fc_time_tm; +/*@ requires valid_timer: \valid_read(timer); + ensures + result_null_or_internal_tm: + \result ≡ &__fc_time_tm ∨ \result ≡ \null; + assigns \result, __fc_time_tm; + assigns \result \from __fc_p_time_tm; + assigns __fc_time_tm \from *timer; + */ +extern struct tm *gmtime(time_t const *timer); + +/*@ requires valid_timer: \valid_read(timer); + ensures + result_null_or_internal_tm: + \result ≡ &__fc_time_tm ∨ \result ≡ \null; + ensures + maybe_error: __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 75; + assigns \result, __fc_time_tm; + assigns \result \from __fc_p_time_tm; + assigns __fc_time_tm \from *timer; + */ +extern struct tm *localtime(time_t const *timer); + +/*@ requires dst_has_room: \valid(s + (0 .. max - 1)); + requires valid_format: valid_read_string(format); + requires valid_tm: \valid_read(tm); + ensures result_bounded: \result ≤ \old(max); + assigns *(s + (0 .. max - 1)), \result; + assigns *(s + (0 .. max - 1)) + \from (indirect: max), (indirect: *(format + (0 ..))), (indirect: *tm); assigns \result - \from (indirect: __fc_sockfds[socket]), (indirect: socket); - assigns *((char *)address + (0 .. *address_len - 1)) - \from (indirect: __fc_sockfds[socket]), (indirect: socket); + \from (indirect: max), (indirect: *(format + (0 ..))), (indirect: *tm); */ -extern int getsockname(int socket, struct sockaddr * restrict address, - socklen_t * restrict address_len); +extern size_t strftime(char * restrict s, size_t max, + char const * restrict format, + struct tm const * restrict tm); -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - requires valid_optlen: \valid(optlen); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns *((char *)optval + (0 ..)), \result, *optlen; - assigns *((char *)optval + (0 ..)) - \from (indirect: sockfd), (indirect: level), (indirect: optname), - (indirect: *optlen), (indirect: optval), - (indirect: __fc_sockfds[sockfd]); +/*@ requires tp: \valid(tp); + assigns \result, *tp, __fc_time; + assigns \result \from __fc_time; + assigns *tp \from __fc_time; + assigns __fc_time \from __fc_time; + + behavior realtime_clock: + assumes realtime: clk_id ≡ 666; + ensures success: \result ≡ 0; + ensures initialization: \initialized(\old(tp)); + + behavior monotonic_clock: + assumes monotonic: clk_id ≡ 1; + ensures success: \result ≡ 0; + ensures initialization: \initialized(\old(tp)); + + behavior bad_clock_id: + assumes bad_id: clk_id ≢ 666 ∧ clk_id ≢ 1; + ensures error: \result ≡ 22; + assigns \result; + assigns \result \from clk_id; + + complete behaviors bad_clock_id, monotonic_clock, realtime_clock; + disjoint behaviors bad_clock_id, monotonic_clock, realtime_clock; + */ +extern int clock_gettime(clockid_t clk_id, struct timespec *tp); + +/*@ +axiomatic nanosleep_predicates { + predicate abs_clock_in_range{L}(clockid_t id, struct timespec *tm) + reads __fc_time; + + predicate valid_clock_id{L}(clockid_t id) + reads __fc_time; + + } + +*/ +/*@ ghost int volatile __fc_interrupted; */ +/*@ requires valid_request: \valid_read(rqtp); + requires + initialization: initialized_request: + \initialized(&rqtp->tv_sec) ∧ \initialized(&rqtp->tv_nsec); + requires valid_nanosecs: 0 ≤ rqtp->tv_nsec < 1000000000; + requires valid_remaining_or_null: rmtp ≡ \null ∨ \valid(rmtp); + assigns \result; assigns \result - \from (indirect: sockfd), (indirect: level), (indirect: optname), - (indirect: *optlen), (indirect: optval), - (indirect: __fc_sockfds[sockfd]); - assigns *optlen - \from (indirect: sockfd), (indirect: level), (indirect: optname), - *optlen, (indirect: optval), (indirect: __fc_sockfds[sockfd]); + \from (indirect: __fc_time), (indirect: __fc_interrupted), + (indirect: clock_id), (indirect: flags), (indirect: rqtp), + (indirect: *rqtp); - behavior so_error: - assumes optname_is_error: level ≡ 1 ∧ optname ≡ 4; - requires valid_optlen: \valid(optlen); - requires optlen_value: *optlen ≡ sizeof(int); - requires valid_optval: \valid((int *)optval); - assigns *((int *)optval), \result; - assigns *((int *)optval) - \from (indirect: sockfd), (indirect: optlen), - (indirect: __fc_sockfds[sockfd]); + behavior absolute: + assumes absolute_time: (flags & 1) ≢ 0; + assumes + no_einval: + abs_clock_in_range(clock_id, rqtp) ∧ valid_clock_id(clock_id); + ensures + result_ok_or_error: + \result ≡ 0 ∨ \result ≡ 4 ∨ \result ≡ 22 ∨ + \result ≡ 95; + assigns \result; assigns \result - \from (indirect: sockfd), (indirect: optlen), - (indirect: __fc_sockfds[sockfd]); + \from (indirect: __fc_time), (indirect: __fc_interrupted), + (indirect: clock_id), (indirect: rqtp), (indirect: *rqtp); - behavior other_options: - assumes optname_not_error: ¬(level ≡ 1 ∧ optname ≡ 4); - requires - optval_null_or_valid: - optval ≡ \null ∨ \valid((char *)optval + (0 ..)); - assigns *((char *)optval + (0 ..)), \result, *optlen; - assigns *((char *)optval + (0 ..)) - \from (indirect: sockfd), (indirect: level), (indirect: optname), - (indirect: *optlen), (indirect: optval), - (indirect: __fc_sockfds[sockfd]); + behavior relative_interrupted: + assumes relative_time: (flags & 1) ≡ 0; + assumes interrupted: __fc_interrupted ≢ 0; + assumes no_einval: valid_clock_id(clock_id); + ensures result_interrupted: \result ≡ 4; + ensures + initialization: interrupted_remaining: + \old(rmtp) ≢ \null ⇒ + \initialized(&\old(rmtp)->tv_sec) ∧ + \initialized(&\old(rmtp)->tv_nsec); + ensures + interrupted_remaining_decreases: + \old(rmtp) ≢ \null ⇒ + \old(rqtp)->tv_sec * 1000000000 + \old(rqtp)->tv_nsec ≥ + \old(rmtp)->tv_sec * 1000000000 + \old(rmtp)->tv_nsec; + ensures + remaining_valid: + \old(rmtp) ≢ \null ⇒ 0 ≤ \old(rmtp)->tv_nsec < 1000000000; + assigns \result, *rmtp; assigns \result - \from (indirect: sockfd), (indirect: level), (indirect: optname), - (indirect: *optlen), (indirect: optval), - (indirect: __fc_sockfds[sockfd]); - assigns *optlen - \from (indirect: sockfd), (indirect: level), (indirect: optname), - *optlen, (indirect: optval), (indirect: __fc_sockfds[sockfd]); + \from (indirect: __fc_time), (indirect: clock_id), (indirect: rqtp), + (indirect: *rqtp); + assigns *rmtp + \from __fc_time, (indirect: clock_id), (indirect: rqtp), + (indirect: *rqtp), (indirect: rmtp); - complete behaviors other_options, so_error; - disjoint behaviors other_options, so_error; + behavior relative_no_error: + assumes relative_time: (flags & 1) ≡ 0; + assumes not_interrupted: __fc_interrupted ≡ 0; + assumes no_einval: valid_clock_id(clock_id); + ensures result_ok: \result ≡ 0; + assigns \result; + assigns \result + \from (indirect: __fc_time), (indirect: clock_id), (indirect: rqtp), + (indirect: *rqtp); + + behavior relative_invalid_clock_id: + assumes relative_time: (flags & 1) ≡ 0; + assumes not_interrupted: __fc_interrupted ≡ 0; + assumes einval: ¬valid_clock_id(clock_id); + ensures result_einval: \result ≡ 22; + assigns \result; + assigns \result + \from (indirect: __fc_time), (indirect: clock_id), (indirect: rqtp), + (indirect: *rqtp); + + complete behaviors relative_invalid_clock_id, + relative_no_error, + relative_interrupted, + absolute; + disjoint behaviors relative_invalid_clock_id, + relative_no_error, + relative_interrupted, + absolute; */ -extern int getsockopt(int sockfd, int level, int optname, void *optval, - socklen_t *optlen); +extern int clock_nanosleep(clockid_t clock_id, int flags, + struct timespec const *rqtp, struct timespec *rmtp); -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result, __fc_sockfds[sockfd]; - assigns \result \from sockfd, __fc_sockfds[sockfd]; - assigns __fc_sockfds[sockfd] \from sockfd, backlog, __fc_sockfds[sockfd]; +/*@ requires valid_timer: \valid_read(timer); + requires valid_result: \valid(result); + ensures + result_null_or_result: \result ≡ \old(result) ∨ \result ≡ \null; + assigns \result, *result; + assigns \result \from (indirect: *timer), result; + assigns *result \from (indirect: *timer); */ -extern int listen(int sockfd, int backlog); +extern struct tm *gmtime_r(time_t const * restrict timer, + struct tm * restrict result); -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - requires valid_buffer_length: \valid((char *)buf + (0 .. len - 1)); +/*@ requires valid_timer: \valid_read(timep); + requires valid_result: \valid(result); ensures - result_error_or_received_length: - \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len)); + result_null_or_initialized: initialization: + (\result ≡ \old(result) ∧ \initialized(\old(result))) ∨ + \result ≡ \null; ensures - initialization: \initialized((char *)\old(buf) + (0 .. \result - 1)); - assigns *((char *)buf + (0 .. len - 1)), __fc_sockfds[sockfd], \result; - assigns *((char *)buf + (0 .. len - 1)) - \from sockfd, len, flags, __fc_sockfds[sockfd]; - assigns __fc_sockfds[sockfd] - \from sockfd, len, flags, __fc_sockfds[sockfd]; - assigns \result \from sockfd, len, flags, __fc_sockfds[sockfd]; - */ -extern ssize_t recv(int sockfd, void *buf, size_t len, int flags); - -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - requires valid_buffer_length: \valid((char *)buf + (0 .. len - 1)); + maybe_error: __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 75; + assigns \result, *result, __fc_errno; + assigns \result \from (indirect: *timep), result; + assigns *result \from (indirect: *timep); + assigns __fc_errno \from (indirect: *timep); + */ +extern struct tm *localtime_r(time_t const * restrict timep, + struct tm * restrict result); + +/*@ requires valid_request: \valid_read(rqtp); requires - valid_addrbuf_or_null: initialization: - (\valid(addrbuf_len) ∧ \initialized(addrbuf_len) ∧ - \valid((char *)addrbuf + (0 .. *addrbuf_len - 1))) ∨ - (addrbuf ≡ \null ∧ addrbuf_len ≡ \null); + initialization: initialized_request: + \initialized(&rqtp->tv_sec) ∧ \initialized(&rqtp->tv_nsec); + requires valid_nanosecs: 0 ≤ rqtp->tv_nsec < 1000000000; + requires valid_remaining_or_null: rmtp ≡ \null ∨ \valid(rmtp); + ensures result_elapsed_or_interrupted: \result ≡ 0 ∨ \result ≡ -1; ensures - result_error_or_received_length: - \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len)); + initialization: interrupted_remaining: + \old(rmtp) ≢ \null ∧ \result ≡ -1 ⇒ + \initialized(&\old(rmtp)->tv_sec) ∧ + \initialized(&\old(rmtp)->tv_nsec); ensures - initialization: buf: - \initialized((char *)\old(buf) + (0 .. \result - 1)); + interrupted_remaining_decreases: + \old(rmtp) ≢ \null ∧ \result ≡ -1 ⇒ + \old(rqtp)->tv_sec * 1000000000 + \old(rqtp)->tv_nsec ≥ + \old(rmtp)->tv_sec * 1000000000 + \old(rmtp)->tv_nsec; ensures - initialization: addrbuf: - \old(addrbuf) ≢ \null ⇒ - \initialized((char *)\old(addrbuf) + (0 .. \old(*addrbuf_len) - 1)); - assigns *((char *)buf + (0 .. len - 1)), __fc_sockfds[sockfd], \result, - *addrbuf_len, *((char *)addrbuf + (0 .. \old(*addrbuf_len) - 1)); - assigns *((char *)buf + (0 .. len - 1)) - \from sockfd, len, flags, __fc_sockfds[sockfd]; - assigns __fc_sockfds[sockfd] - \from sockfd, len, flags, __fc_sockfds[sockfd]; - assigns \result \from sockfd, len, flags, __fc_sockfds[sockfd]; - assigns *addrbuf_len - \from (indirect: sockfd), (indirect: len), (indirect: flags), - __fc_sockfds[sockfd]; - assigns *((char *)addrbuf + (0 .. \old(*addrbuf_len) - 1)) - \from (indirect: sockfd), (indirect: len), (indirect: flags), - __fc_sockfds[sockfd]; + interrupted_remaining_valid: + \old(rmtp) ≢ \null ∧ \result ≡ -1 ⇒ + 0 ≤ \old(rmtp)->tv_nsec < 1000000000; + assigns \result, *rmtp; + assigns \result + \from (indirect: __fc_time), (indirect: rqtp), (indirect: *rqtp); + assigns *rmtp + \from (indirect: __fc_time), (indirect: rqtp), (indirect: *rqtp), + (indirect: rmtp); */ -extern ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, - struct sockaddr *addrbuf, socklen_t *addrbuf_len); +extern int nanosleep(struct timespec const *rqtp, struct timespec *rmtp); -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - requires - msg_control_has_room: - \valid((char *)hdr->msg_control + (0 .. hdr->msg_controllen - 1)); - requires - msg_iov_has_room: \valid(hdr->msg_iov + (0 .. hdr->msg_iovlen - 1)); - requires - msg_name_null_or_has_room: - hdr->msg_name ≡ \null ∨ - \valid((char *)hdr->msg_name + (0 .. hdr->msg_namelen - 1)); - ensures - result_error_or_received_length: - \result ≡ -1 ∨ (0 ≤ \result ≤ \old(hdr)->msg_iovlen); - assigns *((char *)hdr->msg_name + (0 .. hdr->msg_namelen - 1)), - hdr->msg_namelen, - *((char *)(hdr->msg_iov + (0 .. hdr->msg_iovlen - 1))->iov_base + - (0 ..)), - *((char *)hdr->msg_control + (0 .. hdr->msg_controllen - 1)), - \result, hdr->msg_controllen, hdr->msg_flags, - __fc_sockfds[sockfd]; - assigns *((char *)hdr->msg_name + (0 .. hdr->msg_namelen - 1)) - \from __fc_sockfds[sockfd]; - assigns hdr->msg_namelen \from __fc_sockfds[sockfd]; - assigns - *((char *)(hdr->msg_iov + (0 .. hdr->msg_iovlen - 1))->iov_base + (0 ..)) - \from __fc_sockfds[sockfd]; - assigns *((char *)hdr->msg_control + (0 .. hdr->msg_controllen - 1)) - \from __fc_sockfds[sockfd]; - assigns \result \from __fc_sockfds[sockfd]; - assigns hdr->msg_controllen \from __fc_sockfds[sockfd]; - assigns hdr->msg_flags \from __fc_sockfds[sockfd]; - assigns __fc_sockfds[sockfd] \from __fc_sockfds[sockfd]; +extern char *tzname[2]; + +/*@ assigns *(tzname[0 .. 1] + (0 ..)); + assigns *(tzname[0 .. 1] + (0 ..)) \from \nothing; */ -extern ssize_t recvmsg(int sockfd, struct msghdr *hdr, int flags); +extern void tzset(void); -/*@ requires available_sockfd: 0 ≤ sockfd < 1024; - requires buf_len_ok: \valid_read((char *)buf + (0 .. len - 1)); +/*@ requires + valid: + valid_read_or_empty((void *)s, (size_t)(sizeof(wchar_t) * n)) ∨ + \valid_read((unsigned char *)s + (0 .. wmemchr_off(s, c, n))); + requires + initialization: + \initialized(s + (0 .. n - 1)) ∨ + \initialized(s + (0 .. wmemchr_off(s, c, n))); + requires + danglingness: + non_escaping((void *)s, (size_t)(sizeof(wchar_t) * n)) ∨ + non_escaping((void *)s, + (size_t)(sizeof(wchar_t) * (wmemchr_off(s, c, n) + 1))); ensures - error_or_chars_sent: \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len)); - assigns __fc_errno, __fc_sockfds[sockfd], \result; - assigns __fc_errno - \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), - (indirect: *((char *)buf + (0 .. len))), flags; - assigns __fc_sockfds[sockfd] - \from __fc_sockfds[sockfd], *((char *)buf + (0 .. len)), flags; + result_null_or_inside_s: + \result ≡ \null ∨ \subset(\result, \old(s) + (0 .. \old(n) - 1)); + assigns \result; assigns \result - \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), - (indirect: *((char *)buf + (0 .. len))), (indirect: flags); + \from s, (indirect: *(s + (0 .. n - 1))), (indirect: c), (indirect: n); */ -extern ssize_t send(int sockfd, void const *buf, size_t len, int flags); +extern wchar_t *wmemchr(wchar_t const *s, wchar_t c, size_t n); -/*@ requires available_sockfd: 0 ≤ sockfd < 1024; - requires valid_message: \valid_read(message); +/*@ requires + valid_s1: + valid_read_or_empty((void *)s1, (size_t)(sizeof(wchar_t) * n)); requires - valid_msg_iov: - \valid_read(message->msg_iov + (0 .. message->msg_iovlen - 1)); - ensures error_or_chars_sent: \result ≡ -1 ∨ 0 ≤ \result; - assigns __fc_sockfds[sockfd], \result; - assigns __fc_sockfds[sockfd] - \from __fc_sockfds[sockfd], (indirect: *message), - (indirect: *(message->msg_iov + (0 .. message->msg_iovlen - 1))), - (indirect: flags); + valid_s2: + valid_read_or_empty((void *)s2, (size_t)(sizeof(wchar_t) * n)); + requires initialization: s1: \initialized(s1 + (0 .. n - 1)); + requires initialization: s2: \initialized(s2 + (0 .. n - 1)); + requires + danglingness: s1: + non_escaping((void *)s1, (size_t)(sizeof(wchar_t) * n)); + requires + danglingness: s2: + non_escaping((void *)s2, (size_t)(sizeof(wchar_t) * n)); + assigns \result; assigns \result - \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), - (indirect: *message), - (indirect: *(message->msg_iov + (0 .. message->msg_iovlen - 1))); + \from (indirect: *(s1 + (0 .. n - 1))), + (indirect: *(s2 + (0 .. n - 1))), (indirect: n); */ -extern ssize_t sendmsg(int sockfd, struct msghdr const *message, int flags); +extern int wmemcmp(wchar_t const *s1, wchar_t const *s2, size_t n); -/*@ requires available_sockfd: 0 ≤ sockfd < 1024; - requires buf_len_ok: \valid_read((char *)buf + (0 .. len - 1)); +wchar_t *wmemcpy(wchar_t *dest, wchar_t const *src, size_t n); + +/*@ requires valid_src: \valid_read(src + (0 .. n - 1)); + requires valid_dest: \valid(dest + (0 .. n - 1)); + ensures result_ptr: \result ≡ \old(dest); + assigns *(dest + (0 .. n - 1)), \result; + assigns *(dest + (0 .. n - 1)) + \from *(src + (0 .. n - 1)), (indirect: src), (indirect: n); + assigns \result \from dest; + */ +extern wchar_t *wmemmove(wchar_t *dest, wchar_t const *src, size_t n); + +wchar_t *wmemset(wchar_t *dest, wchar_t val, size_t len); + +wchar_t *wcscat(wchar_t *dest, wchar_t const *src); + +/*@ requires valid_wstring_src: valid_read_wstring(wcs); ensures - error_or_chars_sent: \result ≡ -1 ∨ (0 ≤ \result ≤ \old(len)); - assigns __fc_errno, __fc_sockfds[sockfd], \result; - assigns __fc_errno - \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), - (indirect: *((char *)buf + (0 .. len))), flags; - assigns __fc_sockfds[sockfd] - \from __fc_sockfds[sockfd], *((char *)buf + (0 .. len)), flags; - assigns \result - \from (indirect: sockfd), (indirect: __fc_sockfds[sockfd]), - (indirect: *((char *)buf + (0 .. len))), (indirect: flags); + result_null_or_inside_wcs: + \result ≡ \null ∨ \subset(\result, \old(wcs) + (0 ..)); + assigns \result; + assigns \result \from wcs, (indirect: *(wcs + (0 ..))), (indirect: wc); */ -extern ssize_t sendto(int sockfd, void const *buf, size_t len, int flags, - struct sockaddr const *address, socklen_t address_len); +extern wchar_t *wcschr(wchar_t const *wcs, wchar_t wc); -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - requires - optval_null_or_has_room: - optval ≡ \null ∨ \valid_read((char *)optval + (0 .. optlen - 1)); - ensures result_error_or_ok: \result ≡ 0 ∨ \result ≡ -1; - assigns \result, __fc_sockfds[sockfd]; +/*@ requires valid_wstring_s1: valid_read_wstring(s1); + requires valid_wstring_s2: valid_read_wstring(s2); + assigns \result; assigns \result - \from __fc_sockfds[sockfd], level, optname, - *((char *)optval + (0 .. optlen - 1)), optlen; - assigns __fc_sockfds[sockfd] - \from __fc_sockfds[sockfd], level, optname, - *((char *)optval + (0 .. optlen - 1)), optlen; + \from (indirect: *(s1 + (0 ..))), (indirect: *(s2 + (0 ..))); */ -extern int setsockopt(int sockfd, int level, int optname, void const *optval, - socklen_t optlen); +extern int wcscmp(wchar_t const *s1, wchar_t const *s2); -/*@ requires valid_sockfd: 0 ≤ sockfd < 1024; - ensures result_error_or_ok: \result ≡ 0 ∨ \result ≡ -1; - assigns \result, __fc_sockfds[sockfd]; - assigns \result \from how, __fc_sockfds[sockfd]; - assigns __fc_sockfds[sockfd] \from how, __fc_sockfds[sockfd]; +wchar_t *wcscpy(wchar_t *dest, wchar_t const *src); + +/*@ requires valid_wstring_wcs: valid_read_wstring(wcs); + requires valid_wstring_accept: valid_read_wstring(accept); + assigns \result; + assigns \result + \from (indirect: *(wcs + (0 ..))), (indirect: *(accept + (0 ..))); */ -extern int shutdown(int sockfd, int how); +extern size_t wcscspn(wchar_t const *wcs, wchar_t const *accept); -/*@ ensures - result_error_or_valid_new_sockfd: - (0 ≤ \result < 1024) ∨ \result ≡ -1; - assigns \result, __fc_socket_counter; +/*@ requires valid_nwstring_src: valid_read_nwstring(src, n); + requires valid_wstring_dest: valid_wstring(dest); + requires + room_for_concatenation: + \valid(dest + (wcslen(dest) .. wcslen(dest) + \min(wcslen(src), n))); + requires + separation: + \separated( + dest + (0 .. wcslen(dest) + wcslen(src)), src + (0 .. wcslen(src)) + ); + assigns *(dest + (0 ..)), \result; + assigns *(dest + (0 ..)) + \from *(dest + (0 ..)), (indirect: dest), *(src + (0 .. n - 1)), + (indirect: src), (indirect: n); assigns \result - \from (indirect: domain), (indirect: type), (indirect: protocol), - (indirect: __fc_socket_counter); - assigns __fc_socket_counter - \from (indirect: domain), (indirect: type), (indirect: protocol), - __fc_socket_counter; + \from (indirect: *(dest + (0 ..))), (indirect: *(src + (0 .. n - 1))), + (indirect: n); */ -extern int socket(int domain, int type, int protocol); +extern size_t wcslcat(wchar_t * restrict dest, wchar_t const * restrict src, + size_t n); -/*@ requires valid_socket_sector: \valid(sv + (0 .. 1)); - ensures result_error_or_ok: \result ≡ 0 ∨ \result ≡ -1; - ensures initialization: sv: \initialized(\old(sv) + (0 .. 1)); - ensures valid_new_sockfd: sv0: 0 ≤ *(\old(sv) + 0) < 1024; - ensures valid_new_sockfd: sv1: 0 ≤ *(\old(sv) + 1) < 1024; - assigns \result, __fc_socket_counter, *(sv + (0 .. 1)); - assigns \result \from __fc_socket_counter; - assigns __fc_socket_counter \from __fc_socket_counter; - assigns *(sv + (0 .. 1)) \from __fc_socket_counter; +/*@ requires valid_wstring_src: valid_read_wstring(src); + requires room_nwstring: \valid(dest + (0 .. n)); + requires + separation: dest: src: + \separated(dest + (0 .. n - 1), src + (0 .. n - 1)); + assigns *(dest + (0 .. n - 1)), \result; + assigns *(dest + (0 .. n - 1)) + \from *(src + (0 .. n - 1)), (indirect: src), (indirect: n); + assigns \result + \from (indirect: *(dest + (0 .. n - 1))), (indirect: dest), + (indirect: *(src + (0 .. n - 1))), (indirect: src), (indirect: n); */ -extern int socketpair(int domain, int type, int protocol, int sv[2]); - -struct in6_addr const in6addr_any; - -struct in6_addr const in6addr_loopback; +extern size_t wcslcpy(wchar_t *dest, wchar_t const *src, size_t n); -/*@ assigns \result; - assigns \result \from arg; */ -extern uint32_t htonl(uint32_t arg); +size_t wcslen(wchar_t const *str); -/*@ assigns \result; - assigns \result \from arg; */ -extern uint16_t htons(uint16_t arg); +wchar_t *wcsncat(wchar_t *dest, wchar_t const *src, size_t n); -/*@ assigns \result; - assigns \result \from arg; */ -extern uint32_t ntohl(uint32_t arg); +/*@ requires valid_wstring_s1: valid_read_wstring(s1); + requires valid_wstring_s2: valid_read_wstring(s2); + assigns \result; + assigns \result + \from (indirect: *(s1 + (0 .. n - 1))), + (indirect: *(s2 + (0 .. n - 1))), (indirect: n); + */ +extern int wcsncmp(wchar_t const *s1, wchar_t const *s2, size_t n); -/*@ assigns \result; - assigns \result \from arg; */ -extern uint16_t ntohs(uint16_t arg); +wchar_t *wcsncpy(wchar_t *dest, wchar_t const *src, size_t n); -/*@ requires valid_arg: valid_read_string(arg); +/*@ requires valid_wstring_wcs: valid_read_wstring(wcs); + requires valid_wstring_accept: valid_read_wstring(accept); + ensures + result_null_or_inside_wcs: + \result ≡ \null ∨ \subset(\result, \old(wcs) + (0 ..)); assigns \result; - assigns \result \from (indirect: *(arg + (0 ..))); + assigns \result + \from wcs, (indirect: *(wcs + (0 ..))), (indirect: *(accept + (0 ..))); */ -extern in_addr_t inet_addr(char const *arg); +extern wchar_t *wcspbrk(wchar_t const *wcs, wchar_t const *accept); -char volatile __fc_inet_ntoa_array[16]; -char *__fc_inet_ntoa = (char *)(__fc_inet_ntoa_array); -/*@ ensures result_static_string: \result ≡ __fc_inet_ntoa; - ensures result_null_terminated: *(\result + 15) ≡ 0; - ensures result_valid_string: valid_read_string(\result); - assigns \result, *(__fc_inet_ntoa + (0 ..)); - assigns \result \from (indirect: arg), __fc_inet_ntoa; - assigns *(__fc_inet_ntoa + (0 ..)) \from (indirect: arg); +/*@ requires valid_wstring_wcs: valid_read_wstring(wcs); + ensures + result_null_or_inside_wcs: + \result ≡ \null ∨ \subset(\result, \old(wcs) + (0 ..)); + assigns \result; + assigns \result + \from wcs, (indirect: *(wcs + (0 .. wcslen{Old}(wcs)))), (indirect: wc); */ -extern char *inet_ntoa(struct in_addr arg); +extern wchar_t *wcsrchr(wchar_t const *wcs, wchar_t wc); -/*@ assigns \result, *(dst + (0 .. size - 1)); - assigns \result \from dst, af, *((char *)src + (0 ..)); - assigns *(dst + (0 .. size - 1)) \from af, *((char *)src + (0 ..)); +/*@ requires valid_wstring_wcs: valid_read_wstring(wcs); + requires valid_wstring_accept: valid_read_wstring(accept); + assigns \result; + assigns \result + \from (indirect: *(wcs + (0 .. wcslen{Old}(wcs)))), + (indirect: *(accept + (0 .. wcslen{Old}(accept)))); */ -extern char const *inet_ntop(int af, void const *src, char *dst, - socklen_t size); +extern size_t wcsspn(wchar_t const *wcs, wchar_t const *accept); -/*@ assigns \result, *((char *)dst + (0 ..)); - assigns \result \from af, *(src + (..)); - assigns *((char *)dst + (0 ..)) \from af, *(src + (0 ..)); +/*@ requires valid_wstring_haystack: valid_read_wstring(haystack); + requires valid_wstring_needle: valid_read_wstring(needle); + ensures + result_null_or_inside_haystack: + \result ≡ \null ∨ \subset(\result, \old(haystack) + (0 ..)); + assigns \result; + assigns \result + \from haystack, (indirect: *(haystack + (0 ..))), + (indirect: *(needle + (0 ..))); */ -extern int inet_pton(int af, char const *src, void *dst); +extern wchar_t *wcsstr(wchar_t const *haystack, wchar_t const *needle); -int h_errno; -/*@ requires addrinfo_valid: \valid(addrinfo); - ensures allocation: \allocable(\old(addrinfo)); - assigns \nothing; - frees addrinfo; +/*@ requires room_nwstring: \valid(ws + (0 .. n - 1)); + requires valid_stream: \valid(stream); + ensures result_null_or_same: \result ≡ \null ∨ \result ≡ \old(ws); + ensures + terminated_string_on_success: + \result ≢ \null ⇒ valid_wstring(\old(ws)); + assigns *(ws + (0 .. n - 1)), \result; + assigns *(ws + (0 .. n - 1)) \from (indirect: n), (indirect: *stream); + assigns \result \from ws, (indirect: n), (indirect: *stream); */ -extern void freeaddrinfo(struct addrinfo *addrinfo); +extern wchar_t *fgetws(wchar_t * restrict ws, int n, FILE * restrict stream); -char const *__fc_gai_strerror = "<error message reported by gai_strerror>"; -/*@ ensures result_string: \result ≡ __fc_gai_strerror; - ensures result_valid_string: valid_read_string(\result); +/*@ axiomatic wformat_length { + logic ℤ wformat_length{L}(wchar_t *format) ; + + } + +*/ +/*@ requires valid_wstring_ws1: valid_read_wstring(ws1); + requires valid_wstring_ws2: valid_read_wstring(ws2); assigns \result; - assigns \result \from (indirect: errcode), __fc_gai_strerror; + assigns \result + \from (indirect: *(ws1 + (0 ..))), (indirect: *(ws2 + (0 ..))); */ -extern char const *gai_strerror(int errcode); +extern int wcscasecmp(wchar_t const *ws1, wchar_t const *ws2); -int getaddrinfo(char const * restrict nodename, - char const * restrict servname, - struct addrinfo const * restrict hints, - struct addrinfo ** restrict res); +void atomic_thread_fence(memory_order order); -struct hostent *gethostbyname(char const *name); +void atomic_signal_fence(memory_order order); -static unsigned int volatile getaddrinfo_net_state; -/*@ requires - nodename_string: nodename ≡ \null ∨ valid_read_string(nodename); - requires - servname_string: servname ≡ \null ∨ valid_read_string(servname); - requires hints_option: hints ≡ \null ∨ \valid_read(hints); - requires valid_res: \valid(res); - assigns *res, \result, __fc_errno; - assigns *res - \from (indirect: nodename), (indirect: servname), (indirect: hints); - assigns \result - \from (indirect: nodename), (indirect: servname), (indirect: hints); - assigns __fc_errno - \from (indirect: nodename), (indirect: servname), (indirect: hints); - allocates *\old(res); - - behavior empty_request: - assumes empty: nodename ≡ \null ∧ servname ≡ \null; - ensures no_name: \result ≡ -2; - assigns \result; - assigns \result \from (indirect: nodename), (indirect: servname); - - behavior normal_request: - assumes has_name: nodename ≢ \null ∨ servname ≢ \null; - ensures - initialization: allocation: success_or_error: - (\result ≡ 0 ∧ - \fresh{Old, Here}(*\old(res),sizeof(*\old(res))) ∧ - \initialized(*\old(res))) ∨ - \result ≡ -3 ∨ \result ≡ -1 ∨ \result ≡ -4 ∨ - \result ≡ -6 ∨ \result ≡ -10 ∨ \result ≡ -8 ∨ - \result ≡ -7 ∨ \result ≡ -11; - - complete behaviors normal_request, empty_request; - disjoint behaviors normal_request, empty_request; - */ -int getaddrinfo(char const * restrict nodename, - char const * restrict servname, - struct addrinfo const * restrict hints, - struct addrinfo ** restrict res) -{ - int __retres; - if (nodename == (char const *)0) - if (servname == (char const *)0) { - __retres = -2; - goto return_label; - } - switch (getaddrinfo_net_state) { - case (unsigned int)0: __retres = -1; - goto return_label; - case (unsigned int)1: __retres = -3; - goto return_label; - case (unsigned int)2: __retres = -4; - goto return_label; - case (unsigned int)3: __retres = -6; - goto return_label; - case (unsigned int)5: __retres = -8; - goto return_label; - case (unsigned int)6: __retres = -7; - goto return_label; - case (unsigned int)7: - { - __fc_errno = 5; - __retres = -11; - goto return_label; - } - default: - { - struct addrinfo *tmp_0; - struct sockaddr *tmp_2; - int tmp_3; - struct addrinfo *ai = malloc(sizeof(*tmp_0)); - if (! ai) { - __retres = -10; - goto return_label; - } - struct sockaddr *sa = malloc(sizeof(*tmp_2)); - if (! sa) { - __retres = -10; - goto return_label; - } - tmp_3 = Frama_C_interval(0,43); - sa->sa_family = (sa_family_t)tmp_3; - /*@ slevel 15; */ - { - int i = 0; - while (i < 14) { - { - int tmp_4; - tmp_4 = Frama_C_interval(-128,127); - sa->sa_data[i] = (char)tmp_4; - } - i ++; - } - } - /*@ slevel default; */ - ai->ai_flags = 0; - ai->ai_family = (int)sa->sa_family; - ai->ai_socktype = Frama_C_interval(0,5); - ai->ai_protocol = Frama_C_interval(0,IPPROTO_MAX); - ai->ai_addrlen = sizeof(*sa); - ai->ai_addr = sa; - ai->ai_canonname = (char *)malloc((size_t)6); - if (! ai->ai_canonname) { - __retres = -10; - goto return_label; - } - strcpy(ai->ai_canonname,"dummy"); - ai->ai_next = (struct addrinfo *)0; - *res = ai; - __retres = 0; - goto return_label; - } - } - return_label: return __retres; -} +_Bool __fc_atomic_is_lock_free(void *obj); -struct __fc_gethostbyname __fc_ghbn; -static int res_search(char const *dname, int rec_class, int type, - char *answer, int anslen) +void __fc_atomic_store_marker(void *object, unsigned long long desired); + +void __fc_atomic_store_explicit_marker(void *object, + unsigned long long desired, + memory_order order); + +unsigned long long __fc_atomic_load(void *obj, size_t obj_size); + +unsigned long long __fc_atomic_load_explicit(void *object, + memory_order order, + size_t obj_size); + +unsigned long long __fc_atomic_exchange(void *obj, + unsigned long long desired, + size_t obj_size); + +unsigned long long __fc_atomic_exchange_explicit(void *object, + unsigned long long desired, + memory_order order, + size_t obj_size); + +_Bool __fc_atomic_compare_exchange_strong(void *object, void *expected, + unsigned long long desired, + size_t obj_size); + +_Bool __fc_atomic_compare_exchange_strong_explicit(void *object, + void *expected, + unsigned long long desired, + memory_order success, + memory_order failure, + size_t obj_size); + +_Bool __fc_atomic_compare_exchange_weak(void *object, void *expected, + unsigned long long desired, + size_t obj_size); + +_Bool __fc_atomic_compare_exchange_weak_explicit(void *object, + void *expected, + unsigned long long desired, + memory_order success, + memory_order failure, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_add(void *obj, + unsigned long long operand, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_add_explicit(void *obj, + unsigned long long operand, + memory_order order, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_sub(void *obj, + unsigned long long operand, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_sub_explicit(void *obj, + unsigned long long operand, + memory_order order, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_or(void *obj, + unsigned long long operand, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_or_explicit(void *obj, + unsigned long long operand, + memory_order order, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_xor(void *obj, + unsigned long long operand, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_xor_explicit(void *obj, + unsigned long long operand, + memory_order order, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_and(void *obj, + unsigned long long operand, + size_t obj_size); + +unsigned long long __fc_atomic_fetch_and_explicit(void *obj, + unsigned long long operand, + memory_order order, + size_t obj_size); + +_Bool atomic_flag_test_and_set(atomic_flag volatile *object); + +_Bool atomic_flag_test_and_set_explicit(atomic_flag volatile *object, + memory_order order); + +void atomic_flag_clear(atomic_flag volatile *object); + +void atomic_flag_clear_explicit(atomic_flag volatile *object, + memory_order order); + +void __fc_atomic_init_marker(void *obj, unsigned long long value) { - int tmp; - { - int i = 0; - while (i < anslen - 1) { - *(answer + i) = Frama_C_char_interval((char)(-128),(char)127); - i ++; - } - } - *(answer + (anslen - 1)) = (char)0; - tmp = Frama_C_interval(-1,anslen); - return tmp; + return; } -struct hostent *gethostbyname(char const *name) +void atomic_thread_fence(memory_order order) { - struct hostent *__retres; - char buf[128]; - char const *cp; - int n; + return; +} + +void atomic_signal_fence(memory_order order) +{ + return; +} + +_Bool __fc_atomic_is_lock_free(void *obj) +{ + _Bool __retres; int tmp; - __fc_ghbn.host.h_addrtype = 2; - __fc_ghbn.host.h_length = (int)sizeof(struct in_addr); - if ((int)*name >= '0') - if ((int)*name <= '9') { - cp = name; - while (1) { - if (! *cp) { - struct in_addr addr; - cp --; - ; - if ((int)*cp == '.') break; - addr.s_addr = inet_addr(name); - if (addr.s_addr == 0xffffffff) { - __retres = (struct hostent *)0; - goto return_label; - } - memcpy((void *)(__fc_ghbn.host_addr),(void const *)(& addr), - (size_t)__fc_ghbn.host.h_length); - strncpy(__fc_ghbn.hostbuf,name,(size_t)(128 - 1)); - __fc_ghbn.hostbuf[128 - 1] = (char)'\000'; - __fc_ghbn.host.h_name = __fc_ghbn.hostbuf; - __fc_ghbn.host.h_aliases = __fc_ghbn.host_aliases; - __fc_ghbn.host_aliases[0] = (char *)0; - __fc_ghbn.h_addr_ptrs[0] = (char *)(__fc_ghbn.host_addr); - __fc_ghbn.h_addr_ptrs[1] = (char *)0; - __fc_ghbn.host.h_addr_list = __fc_ghbn.h_addr_ptrs; - __retres = & __fc_ghbn.host; - goto return_label; - } - if ((int)*cp < '0') break; - else - if ((int)*cp > '9') break; - else - if ((int)*cp != '.') break; - cp ++; - } - } - n = res_search(name,1,1,buf,(int)sizeof(buf)); - if (n < 0) { - __retres = (struct hostent *)0; - goto return_label; - } tmp = Frama_C_nondet(0,1); - if (tmp) { - __retres = (struct hostent *)0; - goto return_label; - } - else { - struct in_addr addr_0; - addr_0.s_addr = inet_addr(name); - memcpy((void *)(__fc_ghbn.host_addr),(void const *)(& addr_0), - (size_t)__fc_ghbn.host.h_length); - strncpy(__fc_ghbn.hostbuf,name,(size_t)(128 - 1)); - __fc_ghbn.hostbuf[128 - 1] = (char)'\000'; - __fc_ghbn.host.h_name = __fc_ghbn.hostbuf; - __fc_ghbn.host.h_aliases = __fc_ghbn.host_aliases; - __fc_ghbn.host_aliases[0] = (char *)0; - __fc_ghbn.h_addr_ptrs[0] = (char *)(__fc_ghbn.host_addr); - __fc_ghbn.h_addr_ptrs[1] = (char *)0; - __fc_ghbn.host.h_addr_list = __fc_ghbn.h_addr_ptrs; - __retres = & __fc_ghbn.host; + __retres = (_Bool)(tmp != 0); + return __retres; +} + +void __fc_atomic_store_marker(void *object, unsigned long long desired) +{ + return; +} + +void __fc_atomic_store_explicit_marker(void *object, + unsigned long long desired, + memory_order order) +{ + return; +} + +unsigned long long __fc_atomic_load(void *obj, size_t obj_size) +{ + unsigned long long __retres; + if (obj_size == sizeof(char)) { + __retres = (unsigned long long)*((atomic_uchar volatile *)obj); goto return_label; } + else + if (obj_size == sizeof(short)) { + __retres = (unsigned long long)*((atomic_ushort volatile *)obj); + goto return_label; + } + else + if (obj_size == sizeof(int)) { + __retres = (unsigned long long)*((atomic_uint volatile *)obj); + goto return_label; + } + else + if (obj_size == sizeof(long)) { + __retres = (unsigned long long)*((atomic_ulong volatile *)obj); + goto return_label; + } + else + if (obj_size == sizeof(long long)) { + __retres = *((atomic_ullong volatile *)obj); + goto return_label; + } + else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",50,"0"); + __retres = (unsigned long long)0; return_label: return __retres; } -struct in6_addr const in6addr_any = {.s6_addr = {(uint8_t)0}}; -struct in6_addr const in6addr_loopback = - {.s6_addr = {(uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)0, - (uint8_t)1}}; -char __fc_getpw_pw_name[64]; -char __fc_getpw_pw_passwd[64]; -char __fc_getpw_pw_gecos[64]; -char __fc_getpw_pw_dir[64]; -char __fc_getpw_pw_shell[64]; -struct passwd __fc_pwd = - {.pw_name = __fc_getpw_pw_name, - .pw_passwd = __fc_getpw_pw_passwd, - .pw_uid = 0U, - .pw_gid = 0U, - .pw_gecos = __fc_getpw_pw_gecos, - .pw_dir = __fc_getpw_pw_dir, - .pw_shell = __fc_getpw_pw_shell}; -struct passwd *__fc_p_pwd = & __fc_pwd; -/*@ requires valid_name: valid_read_string(name); - ensures - result_null_or_internal_struct: - \result ≡ \null ∨ \result ≡ __fc_p_pwd; - assigns \result, __fc_pwd; - assigns \result \from __fc_p_pwd, (indirect: *(name + (0 ..))); - assigns __fc_pwd \from (indirect: *(name + (0 ..))); - */ -extern struct passwd *getpwnam(char const *name); - -/*@ ensures - result_null_or_internal_struct: - \result ≡ \null ∨ \result ≡ __fc_p_pwd; - assigns \result, __fc_pwd; - assigns \result \from __fc_p_pwd, (indirect: uid); - assigns __fc_pwd \from (indirect: uid); - */ -extern struct passwd *getpwuid(uid_t uid); - -int getpwnam_r(char const *name, struct passwd *pwd, char *buf, - size_t buflen, struct passwd **result); - -int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, - struct passwd **result); +unsigned long long __fc_atomic_load_explicit(void *object, + memory_order order, + size_t obj_size) +{ + unsigned long long tmp; + tmp = __fc_atomic_load(object,obj_size); + return tmp; +} -static int __fc_getpw_init; -static int __fc_getpw_r(struct passwd *pwd, char *buf, size_t buflen, - struct passwd **result) +unsigned long long __fc_atomic_exchange(void *obj, + unsigned long long desired, + size_t obj_size) { - int __retres; - int tmp_2; - if (! __fc_getpw_init) { - __fc_getpw_init = 1; - Frama_C_make_unknown(__fc_getpw_pw_name,(size_t)63); - __fc_getpw_pw_name[63] = (char)0; - Frama_C_make_unknown(__fc_getpw_pw_passwd,(size_t)63); - __fc_getpw_pw_passwd[63] = (char)0; - Frama_C_make_unknown(__fc_getpw_pw_gecos,(size_t)63); - __fc_getpw_pw_gecos[63] = (char)0; - Frama_C_make_unknown(__fc_getpw_pw_dir,(size_t)63); - __fc_getpw_pw_dir[63] = (char)0; - Frama_C_make_unknown(__fc_getpw_pw_shell,(size_t)63); - __fc_getpw_pw_shell[63] = (char)0; - } - tmp_2 = Frama_C_interval(0,1); - if (tmp_2) { - int tmp; - int tmp_0; - int tmp_1; - *result = (struct passwd *)0; - tmp = Frama_C_interval(0,1); - if (tmp) { - __retres = 5; - goto return_label; - } - tmp_0 = Frama_C_interval(0,1); - if (tmp_0) { - __retres = 24; - goto return_label; - } - tmp_1 = Frama_C_interval(0,1); - if (tmp_1) { - __retres = 23; - goto return_label; - } - __retres = 0; - goto return_label; + unsigned long long r = (unsigned long long)0; + if (obj_size == sizeof(char)) { + r = (unsigned long long)*((atomic_uchar volatile *)obj); + *((atomic_uchar volatile *)obj) = (atomic_uchar)desired; } - else { - size_t len; - size_t remaining = buflen; - len = strlen((char const *)__fc_pwd.pw_name); - if (remaining <= len) { - *result = (struct passwd *)0; - __retres = 34; - goto return_label; - } - strcpy(buf,(char const *)__fc_pwd.pw_name); - *(buf + len) = (char)0; - pwd->pw_name = buf; - buf += len + (size_t)1; - remaining -= len; - len = strlen((char const *)__fc_pwd.pw_passwd); - if (remaining <= len) { - *result = (struct passwd *)0; - __retres = 34; - goto return_label; - } - strcpy(buf,(char const *)__fc_pwd.pw_passwd); - *(buf + len) = (char)0; - pwd->pw_passwd = buf; - buf += len + (size_t)1; - remaining -= len; - len = strlen((char const *)__fc_pwd.pw_gecos); - if (remaining <= len) { - *result = (struct passwd *)0; - __retres = 34; - goto return_label; - } - strcpy(buf,(char const *)__fc_pwd.pw_gecos); - *(buf + len) = (char)0; - pwd->pw_gecos = buf; - buf += len + (size_t)1; - remaining -= len; - len = strlen((char const *)__fc_pwd.pw_dir); - if (remaining <= len) { - *result = (struct passwd *)0; - __retres = 34; - goto return_label; - } - strcpy(buf,(char const *)__fc_pwd.pw_dir); - *(buf + len) = (char)0; - pwd->pw_dir = buf; - buf += len + (size_t)1; - remaining -= len; - len = strlen((char const *)__fc_pwd.pw_shell); - if (remaining <= len) { - *result = (struct passwd *)0; - __retres = 34; - goto return_label; + else + if (obj_size == sizeof(short)) { + r = (unsigned long long)*((atomic_ushort volatile *)obj); + *((atomic_ushort volatile *)obj) = (atomic_ushort)desired; } - strcpy(buf,(char const *)__fc_pwd.pw_shell); - *(buf + len) = (char)0; - pwd->pw_shell = buf; - buf += len + (size_t)1; - remaining -= len; - pwd->pw_uid = Frama_C_unsigned_int_interval((unsigned int)0,4294967295U); - pwd->pw_gid = Frama_C_unsigned_int_interval((unsigned int)0,4294967295U); - *result = pwd; - __retres = 0; - goto return_label; - } - return_label: return __retres; + else + if (obj_size == sizeof(int)) { + r = (unsigned long long)*((atomic_uint volatile *)obj); + *((atomic_uint volatile *)obj) = (atomic_uint)desired; + } + else + if (obj_size == sizeof(long)) { + r = (unsigned long long)*((atomic_ulong volatile *)obj); + *((atomic_ulong volatile *)obj) = (atomic_ulong)desired; + } + else + if (obj_size == sizeof(long long)) { + r = *((atomic_ullong volatile *)obj); + *((atomic_ullong volatile *)obj) = desired; + } + else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",79,"0"); + return r; } -/*@ requires valid_name: valid_read_string(name); - requires valid_buf: \valid(buf + (0 .. buflen - 1)); - requires valid_pwd: \valid(pwd); - requires valid_result: \valid(result); - ensures - result_null_or_assigned: - *\old(result) ≡ \null ∨ *\old(result) ≡ \old(pwd); - ensures - result_ok_or_error: \result ≡ 0 ∨ \result ∈ {5, 24, 23, 34}; - assigns \result, __fc_pwd, *pwd, *result, *(buf + (0 .. buflen - 1)); - assigns \result - \from (indirect: __fc_p_pwd), (indirect: *(name + (0 ..))); - assigns __fc_pwd \from (indirect: *(name + (0 ..))); - assigns *pwd \from __fc_p_pwd; - assigns *result \from __fc_p_pwd; - assigns *(buf + (0 .. buflen - 1)) \from (indirect: *__fc_p_pwd); - */ -int getpwnam_r(char const *name, struct passwd *pwd, char *buf, - size_t buflen, struct passwd **result) +unsigned long long __fc_atomic_exchange_explicit(void *object, + unsigned long long desired, + memory_order order, + size_t obj_size) { - int tmp; - /*@ assert valid_read_string(name); */ ; - tmp = __fc_getpw_r(pwd,buf,buflen,result); + unsigned long long tmp; + tmp = __fc_atomic_exchange(object,desired,obj_size); return tmp; } -/*@ requires valid_buf: \valid(buf + (0 .. buflen - 1)); - requires valid_pwd: \valid(pwd); - requires valid_result: \valid(result); - ensures - result_null_or_assigned: - *\old(result) ≡ \null ∨ *\old(result) ≡ \old(pwd); - ensures - result_ok_or_error: \result ≡ 0 ∨ \result ∈ {5, 24, 23, 34}; - assigns \result, __fc_pwd, *pwd, *result, *(buf + (0 .. buflen - 1)); - assigns \result \from (indirect: __fc_p_pwd); - assigns __fc_pwd \from (indirect: uid); - assigns *pwd \from __fc_p_pwd; - assigns *result \from __fc_p_pwd; - assigns *(buf + (0 .. buflen - 1)) \from (indirect: *__fc_p_pwd); - */ -int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, - struct passwd **result) +_Bool __fc_atomic_compare_exchange_strong(void *object, void *expected, + unsigned long long desired, + size_t obj_size) { - int tmp; - tmp = __fc_getpw_r(pwd,buf,buflen,result); - return tmp; + _Bool __retres; + int r = memcmp((void const *)object,(void const *)expected,obj_size); + if (r == 0) memcpy(object,(void const *)(& desired),obj_size); + else memcpy(expected,(void const *)object,obj_size); + __retres = (_Bool)(r == 0); + return __retres; } -/*@ ghost unsigned int volatile __fc_time; */ -/*@ assigns \result; - assigns \result \from __fc_time; */ -extern clock_t clock(void); +_Bool __fc_atomic_compare_exchange_strong_explicit(void *object, + void *expected, + unsigned long long desired, + memory_order success, + memory_order failure, + size_t obj_size) +{ + _Bool tmp; + tmp = __fc_atomic_compare_exchange_strong(object,expected,desired,obj_size); + return tmp; +} -/*@ assigns \result; - assigns \result \from time1, time0; */ -extern double difftime(time_t time1, time_t time0); - -/*@ requires valid_timeptr: \valid(timeptr); - assigns *timeptr, \result; - assigns *timeptr \from *timeptr; - assigns \result \from (indirect: *timeptr); - */ -extern time_t mktime(struct tm *timeptr); - -/*@ assigns *timer, \result; - assigns *timer \from __fc_time; - assigns \result \from __fc_time; - - behavior null: - assumes timer_null: timer ≡ \null; - assigns \result; - assigns \result \from __fc_time; - - behavior not_null: - assumes timer_non_null: timer ≢ \null; - requires valid_timer: \valid(timer); - ensures initialization: timer: \initialized(\old(timer)); - assigns *timer, \result; - assigns *timer \from __fc_time; - assigns \result \from __fc_time; - - complete behaviors not_null, null; - disjoint behaviors not_null, null; - */ -extern time_t time(time_t *timer); - -char __fc_ctime[26]; -char * const __fc_p_ctime = __fc_ctime; -/*@ requires valid_timeptr: \valid_read(timeptr); - requires initialization: init_timeptr: \initialized(timeptr); - ensures result_points_to_ctime: \result ≡ __fc_p_ctime; - ensures result_valid_string: valid_read_string(__fc_p_ctime); - assigns __fc_ctime[0 .. 25], \result; - assigns __fc_ctime[0 .. 25] - \from (indirect: *timeptr), (indirect: __fc_time); - assigns \result - \from (indirect: *timeptr), (indirect: __fc_time), __fc_p_ctime; - */ -extern char *asctime(struct tm const *timeptr); - -/*@ requires valid_timer: \valid_read(timer); - requires initialization: init_timer: \initialized(timer); - ensures result_points_to_ctime: \result ≡ __fc_p_ctime; - ensures result_valid_string: valid_read_string(__fc_p_ctime); - assigns __fc_ctime[0 .. 25], \result; - assigns __fc_ctime[0 .. 25] - \from (indirect: *timer), (indirect: __fc_time); - assigns \result - \from (indirect: *timer), (indirect: __fc_time), __fc_p_ctime; - */ -extern char *ctime(time_t const *timer); - -struct tm __fc_time_tm; -struct tm * const __fc_p_time_tm = & __fc_time_tm; -/*@ requires valid_timer: \valid_read(timer); - ensures - result_null_or_internal_tm: - \result ≡ &__fc_time_tm ∨ \result ≡ \null; - assigns \result, __fc_time_tm; - assigns \result \from __fc_p_time_tm; - assigns __fc_time_tm \from *timer; - */ -extern struct tm *gmtime(time_t const *timer); - -/*@ requires valid_timer: \valid_read(timer); - ensures - result_null_or_internal_tm: - \result ≡ &__fc_time_tm ∨ \result ≡ \null; - ensures - maybe_error: __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 75; - assigns \result, __fc_time_tm; - assigns \result \from __fc_p_time_tm; - assigns __fc_time_tm \from *timer; - */ -extern struct tm *localtime(time_t const *timer); - -/*@ requires dst_has_room: \valid(s + (0 .. max - 1)); - requires valid_format: valid_read_string(format); - requires valid_tm: \valid_read(tm); - ensures result_bounded: \result ≤ \old(max); - assigns *(s + (0 .. max - 1)), \result; - assigns *(s + (0 .. max - 1)) - \from (indirect: max), (indirect: *(format + (0 ..))), (indirect: *tm); - assigns \result - \from (indirect: max), (indirect: *(format + (0 ..))), (indirect: *tm); - */ -extern size_t strftime(char * restrict s, size_t max, - char const * restrict format, - struct tm const * restrict tm); - -/*@ requires tp: \valid(tp); - assigns \result, *tp, __fc_time; - assigns \result \from __fc_time; - assigns *tp \from __fc_time; - assigns __fc_time \from __fc_time; - - behavior realtime_clock: - assumes realtime: clk_id ≡ 666; - ensures success: \result ≡ 0; - ensures initialization: \initialized(\old(tp)); - - behavior monotonic_clock: - assumes monotonic: clk_id ≡ 1; - ensures success: \result ≡ 0; - ensures initialization: \initialized(\old(tp)); - - behavior bad_clock_id: - assumes bad_id: clk_id ≢ 666 ∧ clk_id ≢ 1; - ensures error: \result ≡ 22; - assigns \result; - assigns \result \from clk_id; - - complete behaviors bad_clock_id, monotonic_clock, realtime_clock; - disjoint behaviors bad_clock_id, monotonic_clock, realtime_clock; - */ -extern int clock_gettime(clockid_t clk_id, struct timespec *tp); - -/*@ -axiomatic nanosleep_predicates { - predicate abs_clock_in_range{L}(clockid_t id, struct timespec *tm) - reads __fc_time; - - predicate valid_clock_id{L}(clockid_t id) - reads __fc_time; - - } - -*/ -/*@ ghost int volatile __fc_interrupted; */ -/*@ requires valid_request: \valid_read(rqtp); - requires - initialization: initialized_request: - \initialized(&rqtp->tv_sec) ∧ \initialized(&rqtp->tv_nsec); - requires valid_nanosecs: 0 ≤ rqtp->tv_nsec < 1000000000; - requires valid_remaining_or_null: rmtp ≡ \null ∨ \valid(rmtp); - assigns \result; - assigns \result - \from (indirect: __fc_time), (indirect: __fc_interrupted), - (indirect: clock_id), (indirect: flags), (indirect: rqtp), - (indirect: *rqtp); - - behavior absolute: - assumes absolute_time: (flags & 1) ≢ 0; - assumes - no_einval: - abs_clock_in_range(clock_id, rqtp) ∧ valid_clock_id(clock_id); - ensures - result_ok_or_error: - \result ≡ 0 ∨ \result ≡ 4 ∨ \result ≡ 22 ∨ - \result ≡ 95; - assigns \result; - assigns \result - \from (indirect: __fc_time), (indirect: __fc_interrupted), - (indirect: clock_id), (indirect: rqtp), (indirect: *rqtp); - - behavior relative_interrupted: - assumes relative_time: (flags & 1) ≡ 0; - assumes interrupted: __fc_interrupted ≢ 0; - assumes no_einval: valid_clock_id(clock_id); - ensures result_interrupted: \result ≡ 4; - ensures - initialization: interrupted_remaining: - \old(rmtp) ≢ \null ⇒ - \initialized(&\old(rmtp)->tv_sec) ∧ - \initialized(&\old(rmtp)->tv_nsec); - ensures - interrupted_remaining_decreases: - \old(rmtp) ≢ \null ⇒ - \old(rqtp)->tv_sec * 1000000000 + \old(rqtp)->tv_nsec ≥ - \old(rmtp)->tv_sec * 1000000000 + \old(rmtp)->tv_nsec; - ensures - remaining_valid: - \old(rmtp) ≢ \null ⇒ 0 ≤ \old(rmtp)->tv_nsec < 1000000000; - assigns \result, *rmtp; - assigns \result - \from (indirect: __fc_time), (indirect: clock_id), (indirect: rqtp), - (indirect: *rqtp); - assigns *rmtp - \from __fc_time, (indirect: clock_id), (indirect: rqtp), - (indirect: *rqtp), (indirect: rmtp); - - behavior relative_no_error: - assumes relative_time: (flags & 1) ≡ 0; - assumes not_interrupted: __fc_interrupted ≡ 0; - assumes no_einval: valid_clock_id(clock_id); - ensures result_ok: \result ≡ 0; - assigns \result; - assigns \result - \from (indirect: __fc_time), (indirect: clock_id), (indirect: rqtp), - (indirect: *rqtp); - - behavior relative_invalid_clock_id: - assumes relative_time: (flags & 1) ≡ 0; - assumes not_interrupted: __fc_interrupted ≡ 0; - assumes einval: ¬valid_clock_id(clock_id); - ensures result_einval: \result ≡ 22; - assigns \result; - assigns \result - \from (indirect: __fc_time), (indirect: clock_id), (indirect: rqtp), - (indirect: *rqtp); - - complete behaviors relative_invalid_clock_id, - relative_no_error, - relative_interrupted, - absolute; - disjoint behaviors relative_invalid_clock_id, - relative_no_error, - relative_interrupted, - absolute; - */ -extern int clock_nanosleep(clockid_t clock_id, int flags, - struct timespec const *rqtp, struct timespec *rmtp); - -/*@ requires valid_timer: \valid_read(timer); - requires valid_result: \valid(result); - ensures - result_null_or_result: \result ≡ \old(result) ∨ \result ≡ \null; - assigns \result, *result; - assigns \result \from (indirect: *timer), result; - assigns *result \from (indirect: *timer); - */ -extern struct tm *gmtime_r(time_t const * restrict timer, - struct tm * restrict result); - -/*@ requires valid_timer: \valid_read(timep); - requires valid_result: \valid(result); - ensures - result_null_or_initialized: initialization: - (\result ≡ \old(result) ∧ \initialized(\old(result))) ∨ - \result ≡ \null; - ensures - maybe_error: __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ≡ 75; - assigns \result, *result, __fc_errno; - assigns \result \from (indirect: *timep), result; - assigns *result \from (indirect: *timep); - assigns __fc_errno \from (indirect: *timep); - */ -extern struct tm *localtime_r(time_t const * restrict timep, - struct tm * restrict result); - -/*@ requires valid_request: \valid_read(rqtp); - requires - initialization: initialized_request: - \initialized(&rqtp->tv_sec) ∧ \initialized(&rqtp->tv_nsec); - requires valid_nanosecs: 0 ≤ rqtp->tv_nsec < 1000000000; - requires valid_remaining_or_null: rmtp ≡ \null ∨ \valid(rmtp); - ensures result_elapsed_or_interrupted: \result ≡ 0 ∨ \result ≡ -1; - ensures - initialization: interrupted_remaining: - \old(rmtp) ≢ \null ∧ \result ≡ -1 ⇒ - \initialized(&\old(rmtp)->tv_sec) ∧ - \initialized(&\old(rmtp)->tv_nsec); - ensures - interrupted_remaining_decreases: - \old(rmtp) ≢ \null ∧ \result ≡ -1 ⇒ - \old(rqtp)->tv_sec * 1000000000 + \old(rqtp)->tv_nsec ≥ - \old(rmtp)->tv_sec * 1000000000 + \old(rmtp)->tv_nsec; - ensures - interrupted_remaining_valid: - \old(rmtp) ≢ \null ∧ \result ≡ -1 ⇒ - 0 ≤ \old(rmtp)->tv_nsec < 1000000000; - assigns \result, *rmtp; - assigns \result - \from (indirect: __fc_time), (indirect: rqtp), (indirect: *rqtp); - assigns *rmtp - \from (indirect: __fc_time), (indirect: rqtp), (indirect: *rqtp), - (indirect: rmtp); - */ -extern int nanosleep(struct timespec const *rqtp, struct timespec *rmtp); - -extern char *tzname[2]; - -/*@ assigns *(tzname[0 .. 1] + (0 ..)); - assigns *(tzname[0 .. 1] + (0 ..)) \from \nothing; - */ -extern void tzset(void); - -/*@ requires - valid: - valid_read_or_empty((void *)s, (size_t)(sizeof(wchar_t) * n)) ∨ - \valid_read((unsigned char *)s + (0 .. wmemchr_off(s, c, n))); - requires - initialization: - \initialized(s + (0 .. n - 1)) ∨ - \initialized(s + (0 .. wmemchr_off(s, c, n))); - requires - danglingness: - non_escaping((void *)s, (size_t)(sizeof(wchar_t) * n)) ∨ - non_escaping((void *)s, - (size_t)(sizeof(wchar_t) * (wmemchr_off(s, c, n) + 1))); - ensures - result_null_or_inside_s: - \result ≡ \null ∨ \subset(\result, \old(s) + (0 .. \old(n) - 1)); - assigns \result; - assigns \result - \from s, (indirect: *(s + (0 .. n - 1))), (indirect: c), (indirect: n); - */ -extern wchar_t *wmemchr(wchar_t const *s, wchar_t c, size_t n); - -/*@ requires - valid_s1: - valid_read_or_empty((void *)s1, (size_t)(sizeof(wchar_t) * n)); - requires - valid_s2: - valid_read_or_empty((void *)s2, (size_t)(sizeof(wchar_t) * n)); - requires initialization: s1: \initialized(s1 + (0 .. n - 1)); - requires initialization: s2: \initialized(s2 + (0 .. n - 1)); - requires - danglingness: s1: - non_escaping((void *)s1, (size_t)(sizeof(wchar_t) * n)); - requires - danglingness: s2: - non_escaping((void *)s2, (size_t)(sizeof(wchar_t) * n)); - assigns \result; - assigns \result - \from (indirect: *(s1 + (0 .. n - 1))), - (indirect: *(s2 + (0 .. n - 1))), (indirect: n); - */ -extern int wmemcmp(wchar_t const *s1, wchar_t const *s2, size_t n); - -wchar_t *wmemcpy(wchar_t *dest, wchar_t const *src, size_t n); - -/*@ requires valid_src: \valid_read(src + (0 .. n - 1)); - requires valid_dest: \valid(dest + (0 .. n - 1)); - ensures result_ptr: \result ≡ \old(dest); - assigns *(dest + (0 .. n - 1)), \result; - assigns *(dest + (0 .. n - 1)) - \from *(src + (0 .. n - 1)), (indirect: src), (indirect: n); - assigns \result \from dest; - */ -extern wchar_t *wmemmove(wchar_t *dest, wchar_t const *src, size_t n); - -wchar_t *wmemset(wchar_t *dest, wchar_t val, size_t len); - -wchar_t *wcscat(wchar_t *dest, wchar_t const *src); - -/*@ requires valid_wstring_src: valid_read_wstring(wcs); - ensures - result_null_or_inside_wcs: - \result ≡ \null ∨ \subset(\result, \old(wcs) + (0 ..)); - assigns \result; - assigns \result \from wcs, (indirect: *(wcs + (0 ..))), (indirect: wc); - */ -extern wchar_t *wcschr(wchar_t const *wcs, wchar_t wc); - -/*@ requires valid_wstring_s1: valid_read_wstring(s1); - requires valid_wstring_s2: valid_read_wstring(s2); - assigns \result; - assigns \result - \from (indirect: *(s1 + (0 ..))), (indirect: *(s2 + (0 ..))); - */ -extern int wcscmp(wchar_t const *s1, wchar_t const *s2); - -wchar_t *wcscpy(wchar_t *dest, wchar_t const *src); - -/*@ requires valid_wstring_wcs: valid_read_wstring(wcs); - requires valid_wstring_accept: valid_read_wstring(accept); - assigns \result; - assigns \result - \from (indirect: *(wcs + (0 ..))), (indirect: *(accept + (0 ..))); - */ -extern size_t wcscspn(wchar_t const *wcs, wchar_t const *accept); - -/*@ requires valid_nwstring_src: valid_read_nwstring(src, n); - requires valid_wstring_dest: valid_wstring(dest); - requires - room_for_concatenation: - \valid(dest + (wcslen(dest) .. wcslen(dest) + \min(wcslen(src), n))); - requires - separation: - \separated( - dest + (0 .. wcslen(dest) + wcslen(src)), src + (0 .. wcslen(src)) - ); - assigns *(dest + (0 ..)), \result; - assigns *(dest + (0 ..)) - \from *(dest + (0 ..)), (indirect: dest), *(src + (0 .. n - 1)), - (indirect: src), (indirect: n); - assigns \result - \from (indirect: *(dest + (0 ..))), (indirect: *(src + (0 .. n - 1))), - (indirect: n); - */ -extern size_t wcslcat(wchar_t * restrict dest, wchar_t const * restrict src, - size_t n); - -/*@ requires valid_wstring_src: valid_read_wstring(src); - requires room_nwstring: \valid(dest + (0 .. n)); - requires - separation: dest: src: - \separated(dest + (0 .. n - 1), src + (0 .. n - 1)); - assigns *(dest + (0 .. n - 1)), \result; - assigns *(dest + (0 .. n - 1)) - \from *(src + (0 .. n - 1)), (indirect: src), (indirect: n); - assigns \result - \from (indirect: *(dest + (0 .. n - 1))), (indirect: dest), - (indirect: *(src + (0 .. n - 1))), (indirect: src), (indirect: n); - */ -extern size_t wcslcpy(wchar_t *dest, wchar_t const *src, size_t n); - -size_t wcslen(wchar_t const *str); - -wchar_t *wcsncat(wchar_t *dest, wchar_t const *src, size_t n); - -/*@ requires valid_wstring_s1: valid_read_wstring(s1); - requires valid_wstring_s2: valid_read_wstring(s2); - assigns \result; - assigns \result - \from (indirect: *(s1 + (0 .. n - 1))), - (indirect: *(s2 + (0 .. n - 1))), (indirect: n); - */ -extern int wcsncmp(wchar_t const *s1, wchar_t const *s2, size_t n); - -wchar_t *wcsncpy(wchar_t *dest, wchar_t const *src, size_t n); - -/*@ requires valid_wstring_wcs: valid_read_wstring(wcs); - requires valid_wstring_accept: valid_read_wstring(accept); - ensures - result_null_or_inside_wcs: - \result ≡ \null ∨ \subset(\result, \old(wcs) + (0 ..)); - assigns \result; - assigns \result - \from wcs, (indirect: *(wcs + (0 ..))), (indirect: *(accept + (0 ..))); - */ -extern wchar_t *wcspbrk(wchar_t const *wcs, wchar_t const *accept); - -/*@ requires valid_wstring_wcs: valid_read_wstring(wcs); - ensures - result_null_or_inside_wcs: - \result ≡ \null ∨ \subset(\result, \old(wcs) + (0 ..)); - assigns \result; - assigns \result - \from wcs, (indirect: *(wcs + (0 .. wcslen{Old}(wcs)))), (indirect: wc); - */ -extern wchar_t *wcsrchr(wchar_t const *wcs, wchar_t wc); - -/*@ requires valid_wstring_wcs: valid_read_wstring(wcs); - requires valid_wstring_accept: valid_read_wstring(accept); - assigns \result; - assigns \result - \from (indirect: *(wcs + (0 .. wcslen{Old}(wcs)))), - (indirect: *(accept + (0 .. wcslen{Old}(accept)))); - */ -extern size_t wcsspn(wchar_t const *wcs, wchar_t const *accept); - -/*@ requires valid_wstring_haystack: valid_read_wstring(haystack); - requires valid_wstring_needle: valid_read_wstring(needle); - ensures - result_null_or_inside_haystack: - \result ≡ \null ∨ \subset(\result, \old(haystack) + (0 ..)); - assigns \result; - assigns \result - \from haystack, (indirect: *(haystack + (0 ..))), - (indirect: *(needle + (0 ..))); - */ -extern wchar_t *wcsstr(wchar_t const *haystack, wchar_t const *needle); - -/*@ requires room_nwstring: \valid(ws + (0 .. n - 1)); - requires valid_stream: \valid(stream); - ensures result_null_or_same: \result ≡ \null ∨ \result ≡ \old(ws); - ensures - terminated_string_on_success: - \result ≢ \null ⇒ valid_wstring(\old(ws)); - assigns *(ws + (0 .. n - 1)), \result; - assigns *(ws + (0 .. n - 1)) \from (indirect: n), (indirect: *stream); - assigns \result \from ws, (indirect: n), (indirect: *stream); - */ -extern wchar_t *fgetws(wchar_t * restrict ws, int n, FILE * restrict stream); - -/*@ axiomatic wformat_length { - logic ℤ wformat_length{L}(wchar_t *format) ; - - } - -*/ -/*@ requires valid_wstring_ws1: valid_read_wstring(ws1); - requires valid_wstring_ws2: valid_read_wstring(ws2); - assigns \result; - assigns \result - \from (indirect: *(ws1 + (0 ..))), (indirect: *(ws2 + (0 ..))); - */ -extern int wcscasecmp(wchar_t const *ws1, wchar_t const *ws2); - -void atomic_thread_fence(memory_order order); - -void atomic_signal_fence(memory_order order); - -_Bool __fc_atomic_is_lock_free(void *obj); - -void __fc_atomic_store_marker(void *object, unsigned long long desired); - -void __fc_atomic_store_explicit_marker(void *object, - unsigned long long desired, - memory_order order); - -unsigned long long __fc_atomic_load(void *obj, size_t obj_size); - -unsigned long long __fc_atomic_load_explicit(void *object, - memory_order order, - size_t obj_size); - -unsigned long long __fc_atomic_exchange(void *obj, - unsigned long long desired, - size_t obj_size); - -unsigned long long __fc_atomic_exchange_explicit(void *object, - unsigned long long desired, - memory_order order, - size_t obj_size); - -_Bool __fc_atomic_compare_exchange_strong(void *object, void *expected, - unsigned long long desired, - size_t obj_size); - -_Bool __fc_atomic_compare_exchange_strong_explicit(void *object, - void *expected, - unsigned long long desired, - memory_order success, - memory_order failure, - size_t obj_size); - -_Bool __fc_atomic_compare_exchange_weak(void *object, void *expected, - unsigned long long desired, - size_t obj_size); +_Bool __fc_atomic_compare_exchange_weak(void *object, void *expected, + unsigned long long desired, + size_t obj_size) +{ + _Bool tmp; + tmp = __fc_atomic_compare_exchange_strong(object,expected,desired,obj_size); + return tmp; +} _Bool __fc_atomic_compare_exchange_weak_explicit(void *object, void *expected, unsigned long long desired, memory_order success, memory_order failure, - size_t obj_size); + size_t obj_size) +{ + _Bool tmp; + tmp = __fc_atomic_compare_exchange_strong(object,expected,desired,obj_size); + return tmp; +} unsigned long long __fc_atomic_fetch_add(void *obj, unsigned long long operand, - size_t obj_size); + size_t obj_size) +{ + unsigned long long r = (unsigned long long)0; + if (obj_size == sizeof(char)) { + r = (unsigned long long)*((atomic_uchar volatile *)obj); + *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) + operand); + } + else + if (obj_size == sizeof(short)) { + r = (unsigned long long)*((atomic_ushort volatile *)obj); + *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) + operand); + } + else + if (obj_size == sizeof(int)) { + r = (unsigned long long)*((atomic_uint volatile *)obj); + *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) + operand); + } + else + if (obj_size == sizeof(long)) { + r = (unsigned long long)*((atomic_ulong volatile *)obj); + *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) + operand); + } + else + if (obj_size == sizeof(long long)) { + r = *((atomic_ullong volatile *)obj); + *((atomic_ullong volatile *)obj) += operand; + } + else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",139,"0"); + return r; +} unsigned long long __fc_atomic_fetch_add_explicit(void *obj, unsigned long long operand, memory_order order, - size_t obj_size); + size_t obj_size) +{ + unsigned long long tmp; + tmp = __fc_atomic_fetch_add(obj,operand,obj_size); + return tmp; +} unsigned long long __fc_atomic_fetch_sub(void *obj, unsigned long long operand, - size_t obj_size); + size_t obj_size) +{ + unsigned long long r = (unsigned long long)0; + if (obj_size == sizeof(char)) { + r = (unsigned long long)*((atomic_uchar volatile *)obj); + *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) - operand); + } + else + if (obj_size == sizeof(short)) { + r = (unsigned long long)*((atomic_ushort volatile *)obj); + *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) - operand); + } + else + if (obj_size == sizeof(int)) { + r = (unsigned long long)*((atomic_uint volatile *)obj); + *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) - operand); + } + else + if (obj_size == sizeof(long)) { + r = (unsigned long long)*((atomic_ulong volatile *)obj); + *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) - operand); + } + else + if (obj_size == sizeof(long long)) { + r = *((atomic_ullong volatile *)obj); + *((atomic_ullong volatile *)obj) -= operand; + } + else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",163,"0"); + return r; +} unsigned long long __fc_atomic_fetch_sub_explicit(void *obj, unsigned long long operand, memory_order order, - size_t obj_size); + size_t obj_size) +{ + unsigned long long tmp; + tmp = __fc_atomic_fetch_sub(obj,operand,obj_size); + return tmp; +} unsigned long long __fc_atomic_fetch_or(void *obj, unsigned long long operand, - size_t obj_size); + size_t obj_size) +{ + unsigned long long r = (unsigned long long)0; + if (obj_size == sizeof(char)) { + r = (unsigned long long)*((atomic_uchar volatile *)obj); + *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) | operand); + } + else + if (obj_size == sizeof(short)) { + r = (unsigned long long)*((atomic_ushort volatile *)obj); + *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) | operand); + } + else + if (obj_size == sizeof(int)) { + r = (unsigned long long)*((atomic_uint volatile *)obj); + *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) | operand); + } + else + if (obj_size == sizeof(long)) { + r = (unsigned long long)*((atomic_ulong volatile *)obj); + *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) | operand); + } + else + if (obj_size == sizeof(long long)) { + r = *((atomic_ullong volatile *)obj); + *((atomic_ullong volatile *)obj) |= operand; + } + else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",187,"0"); + return r; +} unsigned long long __fc_atomic_fetch_or_explicit(void *obj, unsigned long long operand, memory_order order, - size_t obj_size); - -unsigned long long __fc_atomic_fetch_xor(void *obj, - unsigned long long operand, - size_t obj_size); - -unsigned long long __fc_atomic_fetch_xor_explicit(void *obj, - unsigned long long operand, - memory_order order, - size_t obj_size); - -unsigned long long __fc_atomic_fetch_and(void *obj, - unsigned long long operand, - size_t obj_size); - -unsigned long long __fc_atomic_fetch_and_explicit(void *obj, - unsigned long long operand, - memory_order order, - size_t obj_size); - -_Bool atomic_flag_test_and_set(atomic_flag volatile *object); - -_Bool atomic_flag_test_and_set_explicit(atomic_flag volatile *object, - memory_order order); - -void atomic_flag_clear(atomic_flag volatile *object); - -void atomic_flag_clear_explicit(atomic_flag volatile *object, - memory_order order); - -void __fc_atomic_init_marker(void *obj, unsigned long long value) -{ - return; -} - -void atomic_thread_fence(memory_order order) -{ - return; -} - -void atomic_signal_fence(memory_order order) -{ - return; -} - -_Bool __fc_atomic_is_lock_free(void *obj) -{ - _Bool __retres; - int tmp; - tmp = Frama_C_nondet(0,1); - __retres = (_Bool)(tmp != 0); - return __retres; -} - -void __fc_atomic_store_marker(void *object, unsigned long long desired) -{ - return; -} - -void __fc_atomic_store_explicit_marker(void *object, - unsigned long long desired, - memory_order order) + size_t obj_size) { - return; + unsigned long long tmp; + tmp = __fc_atomic_fetch_or(obj,operand,obj_size); + return tmp; } -unsigned long long __fc_atomic_load(void *obj, size_t obj_size) +unsigned long long __fc_atomic_fetch_xor(void *obj, + unsigned long long operand, + size_t obj_size) { - unsigned long long __retres; + unsigned long long r = (unsigned long long)0; if (obj_size == sizeof(char)) { - __retres = (unsigned long long)*((atomic_uchar volatile *)obj); - goto return_label; + r = (unsigned long long)*((atomic_uchar volatile *)obj); + *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) ^ operand); } else if (obj_size == sizeof(short)) { - __retres = (unsigned long long)*((atomic_ushort volatile *)obj); - goto return_label; + r = (unsigned long long)*((atomic_ushort volatile *)obj); + *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) ^ operand); } else if (obj_size == sizeof(int)) { - __retres = (unsigned long long)*((atomic_uint volatile *)obj); - goto return_label; + r = (unsigned long long)*((atomic_uint volatile *)obj); + *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) ^ operand); } else if (obj_size == sizeof(long)) { - __retres = (unsigned long long)*((atomic_ulong volatile *)obj); - goto return_label; + r = (unsigned long long)*((atomic_ulong volatile *)obj); + *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) ^ operand); } else if (obj_size == sizeof(long long)) { - __retres = *((atomic_ullong volatile *)obj); - goto return_label; + r = *((atomic_ullong volatile *)obj); + *((atomic_ullong volatile *)obj) ^= operand; } - else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",50,"0"); - __retres = (unsigned long long)0; - return_label: return __retres; + else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",217,"0"); + return r; } -unsigned long long __fc_atomic_load_explicit(void *object, - memory_order order, - size_t obj_size) +unsigned long long __fc_atomic_fetch_xor_explicit(void *obj, + unsigned long long operand, + memory_order order, + size_t obj_size) { unsigned long long tmp; - tmp = __fc_atomic_load(object,obj_size); + tmp = __fc_atomic_fetch_xor(obj,operand,obj_size); return tmp; } -unsigned long long __fc_atomic_exchange(void *obj, - unsigned long long desired, - size_t obj_size) +unsigned long long __fc_atomic_fetch_and(void *obj, + unsigned long long operand, + size_t obj_size) { unsigned long long r = (unsigned long long)0; if (obj_size == sizeof(char)) { r = (unsigned long long)*((atomic_uchar volatile *)obj); - *((atomic_uchar volatile *)obj) = (atomic_uchar)desired; + *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) & operand); } else if (obj_size == sizeof(short)) { r = (unsigned long long)*((atomic_ushort volatile *)obj); - *((atomic_ushort volatile *)obj) = (atomic_ushort)desired; + *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) & operand); } else if (obj_size == sizeof(int)) { r = (unsigned long long)*((atomic_uint volatile *)obj); - *((atomic_uint volatile *)obj) = (atomic_uint)desired; + *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) & operand); } else if (obj_size == sizeof(long)) { r = (unsigned long long)*((atomic_ulong volatile *)obj); - *((atomic_ulong volatile *)obj) = (atomic_ulong)desired; + *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) & operand); } else if (obj_size == sizeof(long long)) { r = *((atomic_ullong volatile *)obj); - *((atomic_ullong volatile *)obj) = desired; + *((atomic_ullong volatile *)obj) &= operand; } - else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",79,"0"); + else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",247,"0"); return r; } -unsigned long long __fc_atomic_exchange_explicit(void *object, - unsigned long long desired, - memory_order order, - size_t obj_size) +unsigned long long __fc_atomic_fetch_and_explicit(void *obj, + unsigned long long operand, + memory_order order, + size_t obj_size) { unsigned long long tmp; - tmp = __fc_atomic_exchange(object,desired,obj_size); + tmp = __fc_atomic_fetch_and(obj,operand,obj_size); return tmp; } -_Bool __fc_atomic_compare_exchange_strong(void *object, void *expected, - unsigned long long desired, - size_t obj_size) +_Bool atomic_flag_test_and_set(atomic_flag volatile *object) { - _Bool __retres; - int r = memcmp((void const *)object,(void const *)expected,obj_size); - if (r == 0) memcpy(object,(void const *)(& desired),obj_size); - else memcpy(expected,(void const *)object,obj_size); - __retres = (_Bool)(r == 0); - return __retres; + _Bool r = (_Bool)((int)object->__fc_val != 0); + object->__fc_val = (unsigned char)1; + return r; +} + +_Bool atomic_flag_test_and_set_explicit(atomic_flag volatile *object, + memory_order order) +{ + _Bool r = (_Bool)((int)object->__fc_val != 0); + object->__fc_val = (unsigned char)1; + return r; +} + +void atomic_flag_clear(atomic_flag volatile *object) +{ + object->__fc_val = (unsigned char)0; + return; +} + +void atomic_flag_clear_explicit(atomic_flag volatile *object, + memory_order order) +{ + object->__fc_val = (unsigned char)0; + return; } -_Bool __fc_atomic_compare_exchange_strong_explicit(void *object, - void *expected, - unsigned long long desired, - memory_order success, - memory_order failure, - size_t obj_size) -{ - _Bool tmp; - tmp = __fc_atomic_compare_exchange_strong(object,expected,desired,obj_size); - return tmp; -} +FILE *__fc_stderr; + +FILE *__fc_stdin; + +FILE *__fc_stdout; + +/*@ requires valid_filename: valid_read_string(filename); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result + \from (indirect: *(filename + (0 .. strlen{Old}(filename)))); + */ +extern int remove(char const *filename); + +/*@ requires valid_old_name: valid_read_string(old_name); + requires valid_new_name: valid_read_string(new_name); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result + \from (indirect: *(old_name + (0 .. strlen{Old}(old_name)))), + (indirect: *(new_name + (0 .. strlen{Old}(new_name)))); + */ +extern int rename(char const *old_name, char const *new_name); + +FILE __fc_fopen[16]; +FILE * const __fc_p_fopen = __fc_fopen; +/*@ ensures + result_null_or_valid_fd: + \result ≡ \null ∨ \subset(\result, &__fc_fopen[0 .. 16 - 1]); + assigns \result; + assigns \result \from __fc_p_fopen; + */ +extern FILE *tmpfile(void); + +char __fc_tmpnam[2048]; +char * const __fc_p_tmpnam = __fc_tmpnam; +/*@ requires valid_s_or_null: s ≡ \null ∨ \valid(s + (0 .. 2048)); + ensures + result_string_or_null: + \result ≡ \null ∨ \result ≡ \old(s) ∨ + \result ≡ __fc_p_tmpnam; + assigns *(__fc_p_tmpnam + (0 .. 2048)), *(s + (0 .. 2048)), \result; + assigns *(__fc_p_tmpnam + (0 .. 2048)) + \from *(__fc_p_tmpnam + (0 .. 2048)), (indirect: s); + assigns *(s + (0 .. 2048)) + \from (indirect: s), *(__fc_p_tmpnam + (0 .. 2048)); + assigns \result \from s, __fc_p_tmpnam; + */ +extern char *tmpnam(char *s); + +/*@ requires valid_stream: \valid(stream); + ensures result_zero_or_EOF: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: stream), (indirect: *stream); + */ +extern int fclose(FILE *stream); + +/*@ requires null_or_valid_stream: stream ≡ \null ∨ \valid_read(stream); + ensures result_zero_or_EOF: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, *stream, __fc_fopen[0 .. 16 - 1]; + assigns \result + \from (indirect: *stream), (indirect: __fc_fopen[0 .. 16 - 1]); + assigns *stream + \from (indirect: stream), *stream, __fc_fopen[0 .. 16 - 1]; + assigns __fc_fopen[0 .. 16 - 1] + \from (indirect: stream), *stream, __fc_fopen[0 .. 16 - 1]; + + behavior flush_all: + assumes all_streams: stream ≡ \null; + assigns __fc_fopen[0 .. 16 - 1], \result; + assigns __fc_fopen[0 .. 16 - 1] \from __fc_fopen[0 .. 16 - 1]; + assigns \result \from (indirect: __fc_fopen[0 .. 16 - 1]); + + behavior flush_stream: + assumes single_stream: stream ≢ \null; + assigns *stream, \result; + assigns *stream \from *stream; + assigns \result \from (indirect: *stream); + + complete behaviors flush_stream, flush_all; + disjoint behaviors flush_stream, flush_all; + */ +extern int fflush(FILE *stream); + +/*@ requires valid_filename: valid_read_string(filename); + requires valid_mode: valid_read_string(mode); + ensures + result_null_or_valid_fd: + \result ≡ \null ∨ \subset(\result, &__fc_fopen[0 .. 16 - 1]); + assigns \result; + assigns \result + \from (indirect: *(filename + (0 .. strlen{Old}(filename)))), + (indirect: *(mode + (0 .. strlen{Old}(mode)))), __fc_p_fopen; + */ +extern FILE *fopen(char const * restrict filename, char const * restrict mode); + +/*@ requires valid_mode: valid_read_string(mode); + ensures + result_null_or_valid_fd: + \result ≡ \null ∨ \subset(\result, &__fc_fopen[0 .. 16 - 1]); + assigns \result, __fc_fopen[fd]; + assigns \result + \from (indirect: fd), (indirect: *(mode + (0 .. strlen{Old}(mode)))), + (indirect: __fc_fopen[fd]), __fc_p_fopen; + assigns __fc_fopen[fd] + \from (indirect: fd), (indirect: *(mode + (0 .. strlen{Old}(mode)))), + (indirect: __fc_fopen[fd]), __fc_p_fopen; + */ +extern FILE *fdopen(int fd, char const *mode); + +/*@ requires valid_filename: valid_read_string(filename); + requires valid_mode: valid_read_string(mode); + requires valid_stream: \valid(stream); + ensures + result_null_or_valid_fd: + \result ≡ \null ∨ \result ∈ &__fc_fopen[0 .. 16 - 1]; + ensures stream_opened: *\old(stream) ∈ __fc_fopen[0 .. 16 - 1]; + assigns \result, *stream; + assigns \result + \from (indirect: *(filename + (..))), (indirect: *(mode + (..))), + __fc_p_fopen, (indirect: stream); + assigns *stream + \from (indirect: *(filename + (..))), (indirect: *(mode + (..))), + __fc_p_fopen, (indirect: stream); + */ +extern FILE *freopen(char const * restrict filename, + char const * restrict mode, FILE * restrict stream); + +/*@ assigns *stream; + assigns *stream \from buf; */ +extern void setbuf(FILE * restrict stream, char * restrict buf); + +/*@ assigns *stream; + assigns *stream \from buf, mode, size; */ +extern int setvbuf(FILE * restrict stream, char * restrict buf, int mode, + size_t size); + +/*@ axiomatic format_length { + logic ℤ format_length{L}(char *format) ; + + } + +*/ +/*@ assigns *stream; + assigns *stream \from *(format + (..)), arg; */ +extern int vfprintf(FILE * restrict stream, char const * restrict format, + va_list arg); + +/*@ assigns *stream; + assigns *stream \from *(format + (..)), *stream; */ +extern int vfscanf(FILE * restrict stream, char const * restrict format, + va_list arg); + +/*@ assigns *__fc_stdout; + assigns *__fc_stdout \from arg; */ +extern int vprintf(char const * restrict format, va_list arg); + +/*@ assigns *__fc_stdin; + assigns *__fc_stdin \from *(format + (..)); */ +extern int vscanf(char const * restrict format, va_list arg); + +/*@ assigns *(s + (0 .. n - 1)); + assigns *(s + (0 .. n - 1)) \from *(format + (..)), arg; + */ +extern int vsnprintf(char * restrict s, size_t n, + char const * restrict format, va_list arg); + +/*@ assigns *(s + (0 ..)); + assigns *(s + (0 ..)) \from *(format + (..)), arg; + */ +extern int vsprintf(char * restrict s, char const * restrict format, + va_list arg); + +int fgetc(FILE * restrict stream); + +char *fgets(char * restrict s, int size, FILE * restrict stream); -_Bool __fc_atomic_compare_exchange_weak(void *object, void *expected, - unsigned long long desired, - size_t obj_size) -{ - _Bool tmp; - tmp = __fc_atomic_compare_exchange_strong(object,expected,desired,obj_size); - return tmp; -} +/*@ requires valid_stream: \valid(stream); + assigns *stream, \result; + assigns *stream \from c, *stream; + assigns \result \from (indirect: *stream); + */ +extern int fputc(int c, FILE *stream); -_Bool __fc_atomic_compare_exchange_weak_explicit(void *object, - void *expected, - unsigned long long desired, - memory_order success, - memory_order failure, - size_t obj_size) -{ - _Bool tmp; - tmp = __fc_atomic_compare_exchange_strong(object,expected,desired,obj_size); - return tmp; -} +/*@ requires valid_string_s: valid_read_string(s); + assigns *stream, \result; + assigns *stream \from *(s + (0 .. strlen{Old}(s))), *stream; + assigns \result + \from (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: *stream); + */ +extern int fputs(char const * restrict s, FILE * restrict stream); -unsigned long long __fc_atomic_fetch_add(void *obj, - unsigned long long operand, - size_t obj_size) -{ - unsigned long long r = (unsigned long long)0; - if (obj_size == sizeof(char)) { - r = (unsigned long long)*((atomic_uchar volatile *)obj); - *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) + operand); - } - else - if (obj_size == sizeof(short)) { - r = (unsigned long long)*((atomic_ushort volatile *)obj); - *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) + operand); - } - else - if (obj_size == sizeof(int)) { - r = (unsigned long long)*((atomic_uint volatile *)obj); - *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) + operand); - } - else - if (obj_size == sizeof(long)) { - r = (unsigned long long)*((atomic_ulong volatile *)obj); - *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) + operand); - } - else - if (obj_size == sizeof(long long)) { - r = *((atomic_ullong volatile *)obj); - *((atomic_ullong volatile *)obj) += operand; - } - else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",139,"0"); - return r; -} +/*@ requires valid_stream: \valid(stream); + assigns \result, *stream; + assigns \result \from *stream; + assigns *stream \from *stream; + */ +extern int getc(FILE *stream); -unsigned long long __fc_atomic_fetch_add_explicit(void *obj, - unsigned long long operand, - memory_order order, - size_t obj_size) -{ - unsigned long long tmp; - tmp = __fc_atomic_fetch_add(obj,operand,obj_size); - return tmp; -} +int getchar(void); -unsigned long long __fc_atomic_fetch_sub(void *obj, - unsigned long long operand, - size_t obj_size) -{ - unsigned long long r = (unsigned long long)0; - if (obj_size == sizeof(char)) { - r = (unsigned long long)*((atomic_uchar volatile *)obj); - *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) - operand); - } - else - if (obj_size == sizeof(short)) { - r = (unsigned long long)*((atomic_ushort volatile *)obj); - *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) - operand); - } - else - if (obj_size == sizeof(int)) { - r = (unsigned long long)*((atomic_uint volatile *)obj); - *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) - operand); +/*@ axiomatic GetsLength { + logic size_t gets_length{L} + reads *__fc_stdin; + } - else - if (obj_size == sizeof(long)) { - r = (unsigned long long)*((atomic_ulong volatile *)obj); - *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) - operand); - } - else - if (obj_size == sizeof(long long)) { - r = *((atomic_ullong volatile *)obj); - *((atomic_ullong volatile *)obj) -= operand; - } - else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",163,"0"); - return r; -} -unsigned long long __fc_atomic_fetch_sub_explicit(void *obj, - unsigned long long operand, - memory_order order, - size_t obj_size) -{ - unsigned long long tmp; - tmp = __fc_atomic_fetch_sub(obj,operand,obj_size); - return tmp; -} +*/ +/*@ requires room_s: \valid(s + (0 .. gets_length)); + ensures result_null_or_same: \result ≡ \old(s) ∨ \result ≡ \null; + assigns *(s + (0 .. gets_length{Old})), \result, *__fc_stdin; + assigns *(s + (0 .. gets_length{Old})) \from *__fc_stdin; + assigns \result \from s, *__fc_stdin; + assigns *__fc_stdin \from *__fc_stdin; + */ +extern char *gets(char *s); -unsigned long long __fc_atomic_fetch_or(void *obj, - unsigned long long operand, - size_t obj_size) -{ - unsigned long long r = (unsigned long long)0; - if (obj_size == sizeof(char)) { - r = (unsigned long long)*((atomic_uchar volatile *)obj); - *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) | operand); - } - else - if (obj_size == sizeof(short)) { - r = (unsigned long long)*((atomic_ushort volatile *)obj); - *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) | operand); - } - else - if (obj_size == sizeof(int)) { - r = (unsigned long long)*((atomic_uint volatile *)obj); - *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) | operand); - } - else - if (obj_size == sizeof(long)) { - r = (unsigned long long)*((atomic_ulong volatile *)obj); - *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) | operand); - } - else - if (obj_size == sizeof(long long)) { - r = *((atomic_ullong volatile *)obj); - *((atomic_ullong volatile *)obj) |= operand; - } - else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",187,"0"); - return r; -} +/*@ requires valid_stream: \valid(stream); + assigns *stream, \result; + assigns *stream \from c, *stream; + assigns \result \from (indirect: *stream); + */ +extern int putc(int c, FILE *stream); -unsigned long long __fc_atomic_fetch_or_explicit(void *obj, - unsigned long long operand, - memory_order order, - size_t obj_size) -{ - unsigned long long tmp; - tmp = __fc_atomic_fetch_or(obj,operand,obj_size); - return tmp; -} +/*@ assigns *__fc_stdout, \result; + assigns *__fc_stdout \from c, *__fc_stdout; + assigns \result \from (indirect: *__fc_stdout); + */ +extern int putchar(int c); -unsigned long long __fc_atomic_fetch_xor(void *obj, - unsigned long long operand, - size_t obj_size) -{ - unsigned long long r = (unsigned long long)0; - if (obj_size == sizeof(char)) { - r = (unsigned long long)*((atomic_uchar volatile *)obj); - *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) ^ operand); - } - else - if (obj_size == sizeof(short)) { - r = (unsigned long long)*((atomic_ushort volatile *)obj); - *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) ^ operand); - } - else - if (obj_size == sizeof(int)) { - r = (unsigned long long)*((atomic_uint volatile *)obj); - *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) ^ operand); - } - else - if (obj_size == sizeof(long)) { - r = (unsigned long long)*((atomic_ulong volatile *)obj); - *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) ^ operand); - } - else - if (obj_size == sizeof(long long)) { - r = *((atomic_ullong volatile *)obj); - *((atomic_ullong volatile *)obj) ^= operand; - } - else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",217,"0"); - return r; -} +/*@ requires valid_string_s: valid_read_string(s); + assigns *__fc_stdout, \result; + assigns *__fc_stdout \from *(s + (0 .. strlen{Old}(s))), *__fc_stdout; + assigns \result + \from (indirect: *(s + (0 .. strlen{Old}(s)))), + (indirect: *__fc_stdout); + */ +extern int puts(char const *s); -unsigned long long __fc_atomic_fetch_xor_explicit(void *obj, - unsigned long long operand, - memory_order order, - size_t obj_size) -{ - unsigned long long tmp; - tmp = __fc_atomic_fetch_xor(obj,operand,obj_size); - return tmp; -} +/*@ requires valid_stream: \valid(stream); + ensures result_ok_or_error: \result ≡ \old(c) ∨ \result ≡ -1; + assigns *stream, \result; + assigns *stream \from (indirect: c); + assigns \result \from (indirect: c), (indirect: *stream); + */ +extern int ungetc(int c, FILE *stream); + +/*@ requires valid_ptr_block: \valid((char *)ptr + (0 .. nmemb * size - 1)); + requires valid_stream: \valid(stream); + ensures size_read: \result ≤ \old(nmemb); + ensures + initialization: + \initialized((char *)\old(ptr) + (0 .. \result * \old(size) - 1)); + assigns *((char *)ptr + (0 .. nmemb * size - 1)), *stream, \result; + assigns *((char *)ptr + (0 .. nmemb * size - 1)) + \from (indirect: size), (indirect: nmemb), (indirect: *stream); + assigns *stream + \from (indirect: size), (indirect: nmemb), (indirect: *stream); + assigns \result \from size, (indirect: *stream); + */ +extern size_t fread(void * restrict ptr, size_t size, size_t nmemb, + FILE * restrict stream); -unsigned long long __fc_atomic_fetch_and(void *obj, - unsigned long long operand, - size_t obj_size) -{ - unsigned long long r = (unsigned long long)0; - if (obj_size == sizeof(char)) { - r = (unsigned long long)*((atomic_uchar volatile *)obj); - *((atomic_uchar volatile *)obj) = (atomic_uchar)((unsigned long long)*((atomic_uchar volatile *)obj) & operand); - } - else - if (obj_size == sizeof(short)) { - r = (unsigned long long)*((atomic_ushort volatile *)obj); - *((atomic_ushort volatile *)obj) = (atomic_ushort)((unsigned long long)*((atomic_ushort volatile *)obj) & operand); - } - else - if (obj_size == sizeof(int)) { - r = (unsigned long long)*((atomic_uint volatile *)obj); - *((atomic_uint volatile *)obj) = (atomic_uint)((unsigned long long)*((atomic_uint volatile *)obj) & operand); - } - else - if (obj_size == sizeof(long)) { - r = (unsigned long long)*((atomic_ulong volatile *)obj); - *((atomic_ulong volatile *)obj) = (atomic_ulong)((unsigned long long)*((atomic_ulong volatile *)obj) & operand); - } - else - if (obj_size == sizeof(long long)) { - r = *((atomic_ullong volatile *)obj); - *((atomic_ullong volatile *)obj) &= operand; - } - else __FC_assert(0 != 0,"FRAMAC_SHARE/libc/stdatomic.c",247,"0"); - return r; -} +/*@ requires + valid_ptr_block: \valid_read((char *)ptr + (0 .. nmemb * size - 1)); + requires valid_stream: \valid(stream); + ensures size_written: \result ≤ \old(nmemb); + assigns *stream, \result; + assigns *stream + \from (indirect: *((char *)ptr + (0 .. nmemb * size - 1))); + assigns \result + \from (indirect: *((char *)ptr + (0 .. nmemb * size - 1))); + */ +extern size_t fwrite(void const * restrict ptr, size_t size, size_t nmemb, + FILE * restrict stream); -unsigned long long __fc_atomic_fetch_and_explicit(void *obj, - unsigned long long operand, - memory_order order, - size_t obj_size) -{ - unsigned long long tmp; - tmp = __fc_atomic_fetch_and(obj,operand,obj_size); - return tmp; -} +/*@ requires valid_stream: \valid(stream); + requires valid_pos: \valid(pos); + ensures initialization: pos: \initialized(\old(pos)); + assigns \result, *pos; + assigns \result \from (indirect: *stream); + assigns *pos \from (indirect: *stream); + */ +extern int fgetpos(FILE * restrict stream, fpos_t * restrict pos); -_Bool atomic_flag_test_and_set(atomic_flag volatile *object) -{ - _Bool r = (_Bool)((int)object->__fc_val != 0); - object->__fc_val = (unsigned char)1; - return r; -} +/*@ requires valid_stream: \valid(stream); + requires whence_enum: whence ≡ 0 ∨ whence ≡ 1 ∨ whence ≡ 2; + ensures + errno_set: __fc_errno ∈ {11, 9, 27, 4, 22, 5, 28, 75, 32, 29, 6}; + assigns *stream, \result, __fc_errno; + assigns *stream \from *stream, (indirect: offset), (indirect: whence); + assigns \result + \from (indirect: *stream), (indirect: offset), (indirect: whence); + assigns __fc_errno + \from (indirect: *stream), (indirect: offset), (indirect: whence); + */ +extern int fseek(FILE *stream, long offset, int whence); -_Bool atomic_flag_test_and_set_explicit(atomic_flag volatile *object, - memory_order order) -{ - _Bool r = (_Bool)((int)object->__fc_val != 0); - object->__fc_val = (unsigned char)1; - return r; -} +/*@ requires valid_stream: \valid(stream); + requires whence_enum: whence ≡ 0 ∨ whence ≡ 1 ∨ whence ≡ 2; + ensures + errno_set: __fc_errno ∈ {11, 9, 27, 4, 22, 5, 28, 75, 32, 29, 6}; + assigns *stream, \result, __fc_errno; + assigns *stream \from *stream, (indirect: offset), (indirect: whence); + assigns \result + \from (indirect: *stream), (indirect: offset), (indirect: whence); + assigns __fc_errno + \from (indirect: *stream), (indirect: offset), (indirect: whence); + */ +extern int fseeko(FILE *stream, off_t offset, int whence); -void atomic_flag_clear(atomic_flag volatile *object) -{ - object->__fc_val = (unsigned char)0; - return; -} +/*@ requires valid_stream: \valid(stream); + requires valid_pos: \valid_read(pos); + requires initialization: pos: \initialized(pos); + ensures errno_set: __fc_errno ∈ {11, 9, 27, 4, 5, 28, 32, 29, 6}; + assigns *stream, \result, __fc_errno; + assigns *stream \from *pos; + assigns \result \from (indirect: *stream), (indirect: *pos); + assigns __fc_errno + \from __fc_errno, (indirect: *stream), (indirect: *pos); + */ +extern int fsetpos(FILE *stream, fpos_t const *pos); -void atomic_flag_clear_explicit(atomic_flag volatile *object, - memory_order order) -{ - object->__fc_val = (unsigned char)0; - return; -} +/*@ requires valid_stream: \valid(stream); + ensures + success_or_error: + \result ≡ -1 ∨ + (\result ≥ 0 ∧ __fc_errno ≡ \old(__fc_errno)); + ensures errno_set: __fc_errno ∈ {9, 75, 29}; + assigns \result, __fc_errno; + assigns \result \from (indirect: *stream); + assigns __fc_errno \from (indirect: *stream); + */ +extern long ftell(FILE *stream); -FILE *__fc_stderr; +/*@ requires valid_stream: \valid(stream); + ensures + success_or_error: + \result ≡ -1 ∨ + (\result ≥ 0 ∧ __fc_errno ≡ \old(__fc_errno)); + ensures errno_set: __fc_errno ∈ {9, 75, 29}; + assigns \result, __fc_errno; + assigns \result \from (indirect: *stream); + assigns __fc_errno \from (indirect: *stream); + */ +extern off_t ftello(FILE *stream); -FILE *__fc_stdin; +/*@ requires valid_stream: \valid(stream); + assigns *stream; + assigns *stream \from \nothing; + */ +extern void rewind(FILE *stream); -FILE *__fc_stdout; +/*@ requires valid_stream: \valid(stream); + assigns *stream; + assigns *stream \from \nothing; + */ +extern void clearerr(FILE *stream); -/*@ requires valid_filename: valid_read_string(filename); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires valid_stream: \valid(stream); assigns \result; - assigns \result - \from (indirect: *(filename + (0 .. strlen{Old}(filename)))); + assigns \result \from (indirect: *stream); */ -extern int remove(char const *filename); +extern int feof(FILE *stream); -/*@ requires valid_old_name: valid_read_string(old_name); - requires valid_new_name: valid_read_string(new_name); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; +/*@ requires valid_stream: \valid(stream); assigns \result; - assigns \result - \from (indirect: *(old_name + (0 .. strlen{Old}(old_name)))), - (indirect: *(new_name + (0 .. strlen{Old}(new_name)))); + assigns \result \from (indirect: *stream); */ -extern int rename(char const *old_name, char const *new_name); +extern int fileno(FILE *stream); -FILE __fc_fopen[16]; -FILE * const __fc_p_fopen = __fc_fopen; -/*@ ensures - result_null_or_valid_fd: - \result ≡ \null ∨ \subset(\result, &__fc_fopen[0 .. 16 - 1]); - assigns \result; - assigns \result \from __fc_p_fopen; +/*@ requires valid_stream: \valid(stream); + assigns *stream; + assigns *stream \from \nothing; */ -extern FILE *tmpfile(void); +extern void flockfile(FILE *stream); -char __fc_tmpnam[2048]; -char * const __fc_p_tmpnam = __fc_tmpnam; -/*@ requires valid_s_or_null: s ≡ \null ∨ \valid(s + (0 .. 2048)); - ensures - result_string_or_null: - \result ≡ \null ∨ \result ≡ \old(s) ∨ - \result ≡ __fc_p_tmpnam; - assigns *(__fc_p_tmpnam + (0 .. 2048)), *(s + (0 .. 2048)), \result; - assigns *(__fc_p_tmpnam + (0 .. 2048)) - \from *(__fc_p_tmpnam + (0 .. 2048)), (indirect: s); - assigns *(s + (0 .. 2048)) - \from (indirect: s), *(__fc_p_tmpnam + (0 .. 2048)); - assigns \result \from s, __fc_p_tmpnam; +/*@ requires valid_stream: \valid(stream); + assigns *stream; + assigns *stream \from \nothing; */ -extern char *tmpnam(char *s); +extern void funlockfile(FILE *stream); + +/*@ requires valid_stream: \valid(stream); + assigns \result, *stream; + assigns \result \from \nothing; + assigns *stream \from \nothing; + */ +extern int ftrylockfile(FILE *stream); /*@ requires valid_stream: \valid(stream); - ensures result_zero_or_EOF: \result ≡ 0 ∨ \result ≡ -1; assigns \result; - assigns \result \from (indirect: stream), (indirect: *stream); + assigns \result \from (indirect: *stream); */ -extern int fclose(FILE *stream); +extern int ferror(FILE *stream); -/*@ requires null_or_valid_stream: stream ≡ \null ∨ \valid_read(stream); - ensures result_zero_or_EOF: \result ≡ 0 ∨ \result ≡ -1; - assigns \result, *stream, __fc_fopen[0 .. 16 - 1]; - assigns \result - \from (indirect: *stream), (indirect: __fc_fopen[0 .. 16 - 1]); - assigns *stream - \from (indirect: stream), *stream, __fc_fopen[0 .. 16 - 1]; - assigns __fc_fopen[0 .. 16 - 1] - \from (indirect: stream), *stream, __fc_fopen[0 .. 16 - 1]; - - behavior flush_all: - assumes all_streams: stream ≡ \null; - assigns __fc_fopen[0 .. 16 - 1], \result; - assigns __fc_fopen[0 .. 16 - 1] \from __fc_fopen[0 .. 16 - 1]; - assigns \result \from (indirect: __fc_fopen[0 .. 16 - 1]); - - behavior flush_stream: - assumes single_stream: stream ≢ \null; - assigns *stream, \result; - assigns *stream \from *stream; - assigns \result \from (indirect: *stream); - - complete behaviors flush_stream, flush_all; - disjoint behaviors flush_stream, flush_all; +/*@ requires valid_string_s: valid_read_string(s); + assigns __fc_stdout; + assigns __fc_stdout \from __fc_errno, *(s + (0 .. strlen{Old}(s))); + */ +extern void perror(char const *s); + +/*@ requires valid_stream: \valid(stream); + assigns \result, *stream; + assigns \result \from *stream; + assigns *stream \from *stream; */ -extern int fflush(FILE *stream); +extern int getc_unlocked(FILE *stream); -/*@ requires valid_filename: valid_read_string(filename); - requires valid_mode: valid_read_string(mode); - ensures - result_null_or_valid_fd: - \result ≡ \null ∨ \subset(\result, &__fc_fopen[0 .. 16 - 1]); - assigns \result; - assigns \result - \from (indirect: *(filename + (0 .. strlen{Old}(filename)))), - (indirect: *(mode + (0 .. strlen{Old}(mode)))), __fc_p_fopen; +/*@ assigns \result; + assigns \result \from *__fc_stdin; */ +extern int getchar_unlocked(void); + +/*@ requires valid_stream: \valid(stream); + assigns *stream, \result; + assigns *stream \from c; + assigns \result \from (indirect: *stream); */ -extern FILE *fopen(char const * restrict filename, char const * restrict mode); +extern int putc_unlocked(int c, FILE *stream); -/*@ requires valid_mode: valid_read_string(mode); - ensures - result_null_or_valid_fd: - \result ≡ \null ∨ \subset(\result, &__fc_fopen[0 .. 16 - 1]); - assigns \result, __fc_fopen[fd]; - assigns \result - \from (indirect: fd), (indirect: *(mode + (0 .. strlen{Old}(mode)))), - (indirect: __fc_fopen[fd]), __fc_p_fopen; - assigns __fc_fopen[fd] - \from (indirect: fd), (indirect: *(mode + (0 .. strlen{Old}(mode)))), - (indirect: __fc_fopen[fd]), __fc_p_fopen; +/*@ assigns *__fc_stdout, \result; + assigns *__fc_stdout \from c; + assigns \result \from (indirect: *__fc_stdout); */ -extern FILE *fdopen(int fd, char const *mode); +extern int putchar_unlocked(int c); -/*@ requires valid_filename: valid_read_string(filename); - requires valid_mode: valid_read_string(mode); - requires valid_stream: \valid(stream); - ensures - result_null_or_valid_fd: - \result ≡ \null ∨ \result ∈ &__fc_fopen[0 .. 16 - 1]; - ensures stream_opened: *\old(stream) ∈ __fc_fopen[0 .. 16 - 1]; - assigns \result, *stream; - assigns \result - \from (indirect: *(filename + (..))), (indirect: *(mode + (..))), - __fc_p_fopen, (indirect: stream); - assigns *stream - \from (indirect: *(filename + (..))), (indirect: *(mode + (..))), - __fc_p_fopen, (indirect: stream); +/*@ requires valid_stream: \valid(stream); + assigns *stream; + assigns *stream \from \nothing; */ -extern FILE *freopen(char const * restrict filename, - char const * restrict mode, FILE * restrict stream); +extern void clearerr_unlocked(FILE *stream); -/*@ assigns *stream; - assigns *stream \from buf; */ -extern void setbuf(FILE * restrict stream, char * restrict buf); +/*@ requires valid_stream: \valid(stream); + assigns \result; + assigns \result \from (indirect: *stream); + */ +extern int feof_unlocked(FILE *stream); -/*@ assigns *stream; - assigns *stream \from buf, mode, size; */ -extern int setvbuf(FILE * restrict stream, char * restrict buf, int mode, - size_t size); +/*@ requires valid_stream: \valid(stream); + assigns \result; + assigns \result \from (indirect: *stream); + */ +extern int ferror_unlocked(FILE *stream); -/*@ axiomatic format_length { - logic ℤ format_length{L}(char *format) ; +/*@ requires valid_stream: \valid(stream); + assigns \result; + assigns \result \from (indirect: *stream); + */ +extern int fileno_unlocked(FILE *stream); + +/*@ axiomatic pipe_streams { + predicate is_open_pipe{L}(FILE *stream) ; } */ -/*@ assigns *stream; - assigns *stream \from *(format + (..)), arg; */ -extern int vfprintf(FILE * restrict stream, char const * restrict format, - va_list arg); +/*@ requires valid_command: valid_read_string(command); + requires valid_type: valid_read_string(type); + ensures + result_error_or_valid_open_pipe: + \result ≡ \null ∨ + (\subset(\result, &__fc_fopen[0 .. 16 - 1]) ∧ is_open_pipe(\result)); + assigns \result, __fc_fopen[0 ..]; + assigns \result + \from (indirect: *command), (indirect: *type), __fc_p_fopen; + assigns __fc_fopen[0 ..] + \from (indirect: *command), (indirect: *type), __fc_fopen[0 ..]; + */ +extern FILE *popen(char const *command, char const *type); -/*@ assigns *stream; - assigns *stream \from *(format + (..)), *stream; */ -extern int vfscanf(FILE * restrict stream, char const * restrict format, - va_list arg); +/*@ requires valid_stream: \valid(stream); + requires open_pipe: is_open_pipe(stream); + ensures closed_stream: ¬is_open_pipe(\old(stream)); + assigns \result; + assigns \result \from (indirect: *stream); + */ +extern int pclose(FILE *stream); -/*@ assigns *__fc_stdout; - assigns *__fc_stdout \from arg; */ -extern int vprintf(char const * restrict format, va_list arg); +ssize_t getline(char **lineptr, size_t *n, FILE *stream); -/*@ assigns *__fc_stdin; - assigns *__fc_stdin \from *(format + (..)); */ -extern int vscanf(char const * restrict format, va_list arg); +FILE *fmemopen(void * restrict buf, size_t size, char const * restrict mode); -/*@ assigns *(s + (0 .. n - 1)); - assigns *(s + (0 .. n - 1)) \from *(format + (..)), arg; - */ -extern int vsnprintf(char * restrict s, size_t n, - char const * restrict format, va_list arg); +int asprintf(char **strp, char const *fmt, void * const *__va_params); -/*@ assigns *(s + (0 ..)); - assigns *(s + (0 ..)) \from *(format + (..)), arg; - */ -extern int vsprintf(char * restrict s, char const * restrict format, - va_list arg); +FILE __fc_initial_stdout = + {.__fc_FILE_id = (unsigned int)1, .__fc_FILE_data = 0U}; +FILE *__fc_stdout = & __fc_initial_stdout; +FILE __fc_initial_stderr = + {.__fc_FILE_id = (unsigned int)2, .__fc_FILE_data = 0U}; +FILE *__fc_stderr = & __fc_initial_stderr; +FILE __fc_initial_stdin = + {.__fc_FILE_id = (unsigned int)0, .__fc_FILE_data = 0U}; +FILE *__fc_stdin = & __fc_initial_stdin; +/*@ requires valid_mode: valid_read_string(mode); */ +static _Bool is_valid_mode(char const *mode) +{ + _Bool __retres; + if (! ((int)*(mode + 0) != 'r')) + if (! ((int)*(mode + 0) != 'w')) + if (! ((int)*(mode + 0) != 'a')) { + __retres = (_Bool)0; + goto return_label; + } + if (! *(mode + 1)) { + __retres = (_Bool)1; + goto return_label; + } + if (! ((int)*(mode + 1) != 'b')) + if (! ((int)*(mode + 1) != '+')) { + __retres = (_Bool)0; + goto return_label; + } + if (! *(mode + 2)) { + __retres = (_Bool)1; + goto return_label; + } + if ((int)*(mode + 2) == (int)*(mode + 1)) { + __retres = (_Bool)0; + goto return_label; + } + else + if (! ((int)*(mode + 2) != 'b')) + if (! ((int)*(mode + 2) != '+')) { + __retres = (_Bool)0; + goto return_label; + } + __retres = (_Bool)(! *(mode + 3)); + return_label: return __retres; +} + +ssize_t getline(char **lineptr, size_t *n, FILE *stream) +{ + ssize_t __retres; + int tmp; + if (! lineptr) goto _LOR; + else + if (! n) goto _LOR; + else + if (! stream) { + _LOR: { + __fc_errno = 22; + __retres = -1; + goto return_label; + } + } + tmp = ferror(stream); + if (tmp) goto _LOR_0; + else { + int tmp_0; + tmp_0 = feof(stream); + if (tmp_0) { + _LOR_0: { + __retres = -1; + goto return_label; + } + } + } + if (! *lineptr) goto _LOR_1; + else + if (*n == (size_t)0) { + _LOR_1: + { + *lineptr = (char *)malloc((size_t)2); + if (! lineptr) { + __fc_errno = 12; + __retres = -1; + goto return_label; + } + *n = (size_t)2; + } + } + size_t cur = (size_t)0; + while (1) { + int tmp_3; + tmp_3 = ferror(stream); + if (tmp_3) break; + else { + int tmp_4; + tmp_4 = feof(stream); + if (tmp_4) break; + } + { + while (cur < *n - (size_t)1) { + int tmp_1; + tmp_1 = fgetc(stream); + char c = (char)tmp_1; + if ((int)c == -1) + if (cur == (size_t)0) { + __retres = -1; + goto return_label; + } + if ((int)c != -1) { + size_t tmp_2; + tmp_2 = cur; + cur ++; + *(*lineptr + tmp_2) = c; + } + if ((int)c == '\n') goto _LOR_2; + else + if ((int)c == -1) { + _LOR_2: + { + *(*lineptr + cur) = (char)'\000'; + __retres = (ssize_t)cur; + goto return_label; + } + } + } + if (*n == (size_t)2147483647) { + __fc_errno = 75; + __retres = -1; + goto return_label; + } + size_t new_size = *n + (size_t)1; + *lineptr = (char *)realloc((void *)*lineptr,new_size); + if (! *lineptr) { + __fc_errno = 12; + __retres = -1; + goto return_label; + } + *n = new_size; + } + } + __retres = -1; + return_label: return __retres; +} -/*@ requires valid_stream: \valid(stream); - ensures result_uchar_or_eof: (0 ≤ \result ≤ 255) ∨ \result ≡ -1; - assigns *stream, \result; - assigns *stream \from *stream; - assigns \result \from (indirect: *stream); +/*@ requires valid_strp: \valid(strp); + requires valid_fmt: valid_read_string(fmt); + ensures result_error_or_written_byes: \result ≡ -1 ∨ \result ≥ 0; + assigns __fc_heap_status, \result, *strp; + assigns __fc_heap_status + \from (indirect: *(fmt + (0 ..))), __fc_heap_status; + assigns \result + \from (indirect: *(fmt + (0 ..))), (indirect: __fc_heap_status); + assigns *strp \from *(fmt + (0 ..)), (indirect: __fc_heap_status); + allocates *\old(strp); */ -extern int fgetc(FILE *stream); +int asprintf(char **strp, char const *fmt, void * const *__va_params) +{ + int __retres; + va_list args; + int tmp; + args = __va_params; + tmp = Frama_C_interval(1,256); + size_t len = (size_t)tmp; + *strp = (char *)malloc(len); + if (! *strp) { + __retres = -1; + goto return_label; + } + Frama_C_make_unknown(*strp,len - 1U); + *(*strp + (len - 1U)) = (char)0; + __retres = (int)len; + return_label: return __retres; +} /*@ requires valid_stream: \valid(stream); requires room_s: \valid(s + (0 .. size - 1)); @@ -6569,1851 +6700,1916 @@ extern int fgetc(FILE *stream); \from (indirect: size), (indirect: *stream); assigns \result \from s, (indirect: size), (indirect: *stream); */ -extern char *fgets(char * restrict s, int size, FILE * restrict stream); - -/*@ requires valid_stream: \valid(stream); - assigns *stream, \result; - assigns *stream \from c, *stream; - assigns \result \from (indirect: *stream); - */ -extern int fputc(int c, FILE *stream); - -/*@ requires valid_string_s: valid_read_string(s); - assigns *stream, \result; - assigns *stream \from *(s + (0 .. strlen{Old}(s))), *stream; - assigns \result - \from (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: *stream); - */ -extern int fputs(char const * restrict s, FILE * restrict stream); - -/*@ requires valid_stream: \valid(stream); - assigns \result, *stream; - assigns \result \from *stream; - assigns *stream \from *stream; - */ -extern int getc(FILE *stream); - -/*@ assigns \result, *__fc_stdin; - assigns \result \from *__fc_stdin; - assigns *__fc_stdin \from *__fc_stdin; - */ -extern int getchar(void); - -/*@ axiomatic GetsLength { - logic size_t gets_length{L} - reads *__fc_stdin; - +char *fgets(char * restrict s, int size, FILE * restrict stream) +{ + char *__retres; + int tmp_0; + tmp_0 = Frama_C_interval(0,1); + if (tmp_0) { + int tmp; + int possible_errors[7] = {11, 9, 4, 5, 75, 12, 6}; + tmp = Frama_C_interval(0, + (int)(sizeof(possible_errors) / sizeof(int) - (unsigned int)1)); + __fc_errno = possible_errors[tmp]; + __retres = (char *)0; + goto return_label; + } + int i = 0; + while (i < size - 1) { + { + int tmp_1; + int tmp_2; + tmp_1 = Frama_C_interval(0,1); + if (tmp_1) { + *(s + i) = (char)0; + __retres = s; + goto return_label; } - -*/ -/*@ requires room_s: \valid(s + (0 .. gets_length)); - ensures result_null_or_same: \result ≡ \old(s) ∨ \result ≡ \null; - assigns *(s + (0 .. gets_length{Old})), \result, *__fc_stdin; - assigns *(s + (0 .. gets_length{Old})) \from *__fc_stdin; - assigns \result \from s, *__fc_stdin; - assigns *__fc_stdin \from *__fc_stdin; - */ -extern char *gets(char *s); - -/*@ requires valid_stream: \valid(stream); - assigns *stream, \result; - assigns *stream \from c, *stream; - assigns \result \from (indirect: *stream); - */ -extern int putc(int c, FILE *stream); - -/*@ assigns *__fc_stdout, \result; - assigns *__fc_stdout \from c, *__fc_stdout; - assigns \result \from (indirect: *__fc_stdout); - */ -extern int putchar(int c); - -/*@ requires valid_string_s: valid_read_string(s); - assigns *__fc_stdout, \result; - assigns *__fc_stdout \from *(s + (0 .. strlen{Old}(s))), *__fc_stdout; - assigns \result - \from (indirect: *(s + (0 .. strlen{Old}(s)))), - (indirect: *__fc_stdout); - */ -extern int puts(char const *s); - -/*@ requires valid_stream: \valid(stream); - ensures result_ok_or_error: \result ≡ \old(c) ∨ \result ≡ -1; - assigns *stream, \result; - assigns *stream \from (indirect: c); - assigns \result \from (indirect: c), (indirect: *stream); - */ -extern int ungetc(int c, FILE *stream); - -/*@ requires valid_ptr_block: \valid((char *)ptr + (0 .. nmemb * size - 1)); - requires valid_stream: \valid(stream); - ensures size_read: \result ≤ \old(nmemb); - ensures - initialization: - \initialized((char *)\old(ptr) + (0 .. \result * \old(size) - 1)); - assigns *((char *)ptr + (0 .. nmemb * size - 1)), *stream, \result; - assigns *((char *)ptr + (0 .. nmemb * size - 1)) - \from (indirect: size), (indirect: nmemb), (indirect: *stream); - assigns *stream - \from (indirect: size), (indirect: nmemb), (indirect: *stream); - assigns \result \from size, (indirect: *stream); - */ -extern size_t fread(void * restrict ptr, size_t size, size_t nmemb, - FILE * restrict stream); - -/*@ requires - valid_ptr_block: \valid_read((char *)ptr + (0 .. nmemb * size - 1)); - requires valid_stream: \valid(stream); - ensures size_written: \result ≤ \old(nmemb); - assigns *stream, \result; - assigns *stream - \from (indirect: *((char *)ptr + (0 .. nmemb * size - 1))); - assigns \result - \from (indirect: *((char *)ptr + (0 .. nmemb * size - 1))); - */ -extern size_t fwrite(void const * restrict ptr, size_t size, size_t nmemb, - FILE * restrict stream); - -/*@ requires valid_stream: \valid(stream); - requires valid_pos: \valid(pos); - ensures initialization: pos: \initialized(\old(pos)); - assigns \result, *pos; - assigns \result \from (indirect: *stream); - assigns *pos \from (indirect: *stream); - */ -extern int fgetpos(FILE * restrict stream, fpos_t * restrict pos); - -/*@ requires valid_stream: \valid(stream); - requires whence_enum: whence ≡ 0 ∨ whence ≡ 1 ∨ whence ≡ 2; - ensures - errno_set: __fc_errno ∈ {11, 9, 27, 4, 22, 5, 28, 75, 32, 29, 6}; - assigns *stream, \result, __fc_errno; - assigns *stream \from *stream, (indirect: offset), (indirect: whence); - assigns \result - \from (indirect: *stream), (indirect: offset), (indirect: whence); - assigns __fc_errno - \from (indirect: *stream), (indirect: offset), (indirect: whence); - */ -extern int fseek(FILE *stream, long offset, int whence); - -/*@ requires valid_stream: \valid(stream); - requires whence_enum: whence ≡ 0 ∨ whence ≡ 1 ∨ whence ≡ 2; - ensures - errno_set: __fc_errno ∈ {11, 9, 27, 4, 22, 5, 28, 75, 32, 29, 6}; - assigns *stream, \result, __fc_errno; - assigns *stream \from *stream, (indirect: offset), (indirect: whence); - assigns \result - \from (indirect: *stream), (indirect: offset), (indirect: whence); - assigns __fc_errno - \from (indirect: *stream), (indirect: offset), (indirect: whence); - */ -extern int fseeko(FILE *stream, off_t offset, int whence); - -/*@ requires valid_stream: \valid(stream); - requires valid_pos: \valid_read(pos); - requires initialization: pos: \initialized(pos); - ensures errno_set: __fc_errno ∈ {11, 9, 27, 4, 5, 28, 32, 29, 6}; - assigns *stream, \result, __fc_errno; - assigns *stream \from *pos; - assigns \result \from (indirect: *stream), (indirect: *pos); - assigns __fc_errno - \from __fc_errno, (indirect: *stream), (indirect: *pos); - */ -extern int fsetpos(FILE *stream, fpos_t const *pos); - -/*@ requires valid_stream: \valid(stream); - ensures - success_or_error: - \result ≡ -1 ∨ - (\result ≥ 0 ∧ __fc_errno ≡ \old(__fc_errno)); - ensures errno_set: __fc_errno ∈ {9, 75, 29}; - assigns \result, __fc_errno; - assigns \result \from (indirect: *stream); - assigns __fc_errno \from (indirect: *stream); - */ -extern long ftell(FILE *stream); - -/*@ requires valid_stream: \valid(stream); - ensures - success_or_error: - \result ≡ -1 ∨ - (\result ≥ 0 ∧ __fc_errno ≡ \old(__fc_errno)); - ensures errno_set: __fc_errno ∈ {9, 75, 29}; - assigns \result, __fc_errno; - assigns \result \from (indirect: *stream); - assigns __fc_errno \from (indirect: *stream); - */ -extern off_t ftello(FILE *stream); - -/*@ requires valid_stream: \valid(stream); - assigns *stream; - assigns *stream \from \nothing; - */ -extern void rewind(FILE *stream); - -/*@ requires valid_stream: \valid(stream); - assigns *stream; - assigns *stream \from \nothing; - */ -extern void clearerr(FILE *stream); - -/*@ requires valid_stream: \valid(stream); - assigns \result; - assigns \result \from (indirect: *stream); - */ -extern int feof(FILE *stream); + tmp_2 = Frama_C_interval(-128,127); + char c = (char)tmp_2; + *(s + i) = c; + if ((int)c == '\n') { + *(s + (i + 1)) = (char)0; + __retres = s; + goto return_label; + } + } + i ++; + } + *(s + i) = (char)0; + __retres = s; + return_label: return __retres; +} /*@ requires valid_stream: \valid(stream); - assigns \result; + ensures result_uchar_or_eof: (0 ≤ \result ≤ 255) ∨ \result ≡ -1; + assigns *stream, \result; + assigns *stream \from *stream; assigns \result \from (indirect: *stream); */ -extern int fileno(FILE *stream); +int fgetc(FILE * restrict stream) +{ + int __retres; + int tmp_0; + int tmp_2; + tmp_0 = Frama_C_interval(0,1); + if (tmp_0) { + int tmp; + int possible_errors[7] = {11, 9, 4, 5, 75, 12, 6}; + tmp = Frama_C_interval(0, + (int)(sizeof(possible_errors) / sizeof(int) - (unsigned int)1)); + __fc_errno = possible_errors[tmp]; + __retres = -1; + goto return_label; + } + tmp_2 = Frama_C_interval(0,1); + if (tmp_2) { + __retres = -1; + goto return_label; + } + else { + unsigned char tmp_1; + tmp_1 = Frama_C_unsigned_char_interval((unsigned char)0, + (unsigned char)255); + __retres = (int)tmp_1; + goto return_label; + } + return_label: return __retres; +} -/*@ requires valid_stream: \valid(stream); - assigns *stream; - assigns *stream \from \nothing; +/*@ assigns \result, *__fc_stdin; + assigns \result \from *__fc_stdin; + assigns *__fc_stdin \from *__fc_stdin; */ -extern void flockfile(FILE *stream); +int getchar(void) +{ + int tmp; + tmp = fgetc(__fc_stdin); + return tmp; +} -/*@ requires valid_stream: \valid(stream); - assigns *stream; - assigns *stream \from \nothing; +/*@ requires + valid_or_null_buff: + buf ≡ \null ∨ \valid((char *)buf + (0 .. size - 1)); + requires valid_mode: valid_read_string(mode); + ensures + result_error_or_valid: + \result ≡ \null ∨ \result ∈ &__fc_fopen[0 .. 16 - 1]; + ensures + errno_set: + __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ∈ {22, 24, 12}; + assigns __fc_errno, \result; + assigns __fc_errno + \from (indirect: buf), (indirect: size), + (indirect: *(mode + (0 .. strlen{Old}(mode)))); + assigns \result + \from __fc_p_fopen, (indirect: buf), (indirect: size), + (indirect: *(mode + (0 .. strlen{Old}(mode)))); + allocates \old(buf); */ -extern void funlockfile(FILE *stream); +FILE *fmemopen(void * restrict buf, size_t size, char const * restrict mode) +{ + FILE *__retres; + _Bool tmp; + int tmp_1; + int tmp_2; + tmp = is_valid_mode(mode); + if (! tmp) { + __fc_errno = 22; + __retres = (FILE *)0; + goto return_label; + } + if (! buf) { + if (size == (size_t)0) { + int tmp_0; + tmp_0 = Frama_C_interval(0,1); + if (tmp_0) { + __fc_errno = 22; + __retres = (FILE *)0; + goto return_label; + } + } + if ((int)*(mode + 1) != '+') + if (*(mode + 1)) + if ((int)*(mode + 2) != '+') { + __fc_errno = 22; + __retres = (FILE *)0; + goto return_label; + } + buf = malloc(size); + if (! buf) { + __fc_errno = 12; + __retres = (FILE *)0; + goto return_label; + } + } + tmp_1 = Frama_C_interval(0,1); + if (tmp_1) { + __fc_errno = 24; + __retres = (FILE *)0; + goto return_label; + } + tmp_2 = Frama_C_interval(0,16 - 1); + __retres = & __fc_fopen[tmp_2]; + return_label: return __retres; +} -/*@ requires valid_stream: \valid(stream); - assigns \result, *stream; - assigns \result \from \nothing; - assigns *stream \from \nothing; +/*@ requires abs_representable: i > -2147483647 - 1; + assigns \result; + assigns \result \from i; + + behavior negative: + assumes negative: i < 0; + ensures opposite_result: \result ≡ -\old(i); + + behavior nonnegative: + assumes nonnegative: i ≥ 0; + ensures same_result: \result ≡ \old(i); + + complete behaviors nonnegative, negative; + disjoint behaviors nonnegative, negative; */ -extern int ftrylockfile(FILE *stream); +int abs(int i) +{ + int __retres; + if (i < 0) { + __retres = - i; + goto return_label; + } + __retres = i; + return_label: return __retres; +} -/*@ requires valid_stream: \valid(stream); +/*@ requires valid_nptr: \valid_read(p); assigns \result; - assigns \result \from (indirect: *stream); + assigns \result \from (indirect: p), (indirect: *(p + (0 ..))); */ -extern int ferror(FILE *stream); +int atoi(char const *p) +{ + int __retres; + int n; + int c; + int tmp_1; + int tmp_3; + int neg = 0; + unsigned char *up = (unsigned char *)p; + c = (int)*up; + tmp_1 = isdigit(c); + if (! tmp_1) { + int tmp_0; + while (1) { + int tmp; + tmp = isspace(c); + if (! tmp) break; + up ++; + c = (int)*up; + } + switch (c) { + case '-': neg ++; + case '+': { /* sequence */ + up ++; + c = (int)*up; + } + } + tmp_0 = isdigit(c); + if (! tmp_0) { + __retres = 0; + goto return_label; + } + } + n = '0' - c; + while (1) { + int tmp_2; + up ++; + c = (int)*up; + tmp_2 = isdigit(c); + if (! tmp_2) break; + n *= 10; + n += '0' - c; + } + if (neg) tmp_3 = n; else tmp_3 = - n; + __retres = tmp_3; + return_label: return __retres; +} -/*@ requires valid_string_s: valid_read_string(s); - assigns __fc_stdout; - assigns __fc_stdout \from __fc_errno, *(s + (0 .. strlen{Old}(s))); +/*@ assigns __fc_heap_status, \result; + assigns __fc_heap_status + \from (indirect: nmemb), (indirect: size), __fc_heap_status; + assigns \result + \from (indirect: nmemb), (indirect: size), (indirect: __fc_heap_status); + allocates \result; + + behavior allocation: + assumes can_allocate: is_allocable(nmemb * size); + ensures + allocation: \fresh{Old, Here}(\result,\old(nmemb) * \old(size)); + ensures + initialization: + \initialized((char *)\result + (0 .. \old(nmemb) * \old(size) - 1)); + ensures + zero_initialization: + \subset(*((char *)\result + (0 .. \old(nmemb) * \old(size) - 1)), + {0}); + + behavior no_allocation: + assumes cannot_allocate: ¬is_allocable(nmemb * size); + ensures null_result: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; */ -extern void perror(char const *s); +void *calloc(size_t nmemb, size_t size) +{ + void *__retres; + size_t l = nmemb * size; + if (size != (size_t)0) + if (l / size != nmemb) { + __retres = (void *)0; + goto return_label; + } + char *p = malloc(l); + if (p) memset((void *)p,0,l); + __retres = (void *)p; + return_label: return __retres; +} + +static char __fc_env_strings[64]; +static char __fc_initenv_init; +static void __fc_initenv(void) +{ + if (! __fc_initenv_init) { + Frama_C_make_unknown(__fc_env_strings,(size_t)(64 - 1)); + { + int i = 0; + while (i < 4096) { + { + int tmp; + tmp = Frama_C_interval(0,64 - 1); + __fc_env[i] = & __fc_env_strings[tmp]; + } + i ++; + } + } + __fc_initenv_init = (char)1; + } + return; +} -/*@ requires valid_stream: \valid(stream); - assigns \result, *stream; - assigns \result \from *stream; - assigns *stream \from *stream; +/*@ requires valid_name: valid_read_string(name); + ensures null_or_valid_result: \result ≡ \null ∨ \valid(\result); + assigns \result; + assigns \result \from __fc_env[0 ..], (indirect: name), *(name + (0 ..)); */ -extern int getc_unlocked(FILE *stream); - -/*@ assigns \result; - assigns \result \from *__fc_stdin; */ -extern int getchar_unlocked(void); +char *getenv(char const *name) +{ + char *__retres; + int tmp_0; + /*@ assert ¬(strchr(name, '=') ≡ \true); */ ; + __fc_initenv(); + tmp_0 = Frama_C_nondet(0,1); + if (tmp_0) { + int tmp; + tmp = Frama_C_interval(0,4096 - 1); + ; + __retres = __fc_env[tmp]; + goto return_label; + } + else { + __retres = (char *)0; + goto return_label; + } + return_label: return __retres; +} -/*@ requires valid_stream: \valid(stream); - assigns *stream, \result; - assigns *stream \from c; - assigns \result \from (indirect: *stream); +/*@ requires valid_string: valid_read_string(string); + assigns __fc_env[0 ..], \result; + assigns __fc_env[0 ..] \from __fc_env[0 ..], string; + assigns \result \from (indirect: __fc_env[0 ..]), (indirect: string); */ -extern int putc_unlocked(int c, FILE *stream); +int putenv(char *string) +{ + int __retres; + int tmp_3; + char *separator __attribute__((__unused__)) = + strchr((char const *)string,'='); + /*@ assert string_contains_separator: separator ≢ \null; */ ; + /*@ assert name_is_not_empty: separator ≢ string; */ ; + __fc_initenv(); + tmp_3 = Frama_C_nondet(0,1); + if (tmp_3) { + int tmp_1; + int tmp_2; + tmp_1 = Frama_C_nondet(0,1); + if (tmp_1) { + int tmp_0; + tmp_0 = Frama_C_interval(-2147483647 - 1,2147483647); + __retres = tmp_0; + goto return_label; + } + tmp_2 = Frama_C_interval(0,4096 - 1); + __fc_env[tmp_2] = string; + } + __retres = 0; + return_label: return __retres; +} -/*@ assigns *__fc_stdout, \result; - assigns *__fc_stdout \from c; - assigns \result \from (indirect: *__fc_stdout); +/*@ requires valid_name: valid_read_string(name); + requires valid_value: valid_read_string(value); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, __fc_env[0 ..]; + assigns \result + \from __fc_env[0 ..], (indirect: name), (indirect: *(name + (0 ..))), + (indirect: value), (indirect: *(value + (0 ..))), + (indirect: overwrite); + assigns __fc_env[0 ..] + \from __fc_env[0 ..], (indirect: name), (indirect: *(name + (0 ..))), + (indirect: value), (indirect: *(value + (0 ..))), + (indirect: overwrite); */ -extern int putchar_unlocked(int c); +int setenv(char const *name, char const *value, int overwrite) +{ + int __retres; + char *tmp; + int tmp_4; + tmp = strchr(name,'='); + if (tmp) { + __retres = -1; + goto return_label; + } + size_t namelen = strlen(name); + if (namelen == (size_t)0) { + __retres = -1; + goto return_label; + } + __fc_initenv(); + tmp_4 = Frama_C_nondet(0,1); + if (tmp_4) { + __retres = -1; + goto return_label; + } + else { + int tmp_1; + int tmp_2; + int tmp_3; + tmp_1 = Frama_C_nondet(0,1); + if (tmp_1) Frama_C_make_unknown(__fc_env_strings,(size_t)(64 - 1)); + tmp_2 = Frama_C_interval(0,4096 - 1); + tmp_3 = Frama_C_interval(0,64 - 1); + __fc_env[tmp_2] = & __fc_env_strings[tmp_3]; + __retres = 0; + goto return_label; + } + return_label: return __retres; +} -/*@ requires valid_stream: \valid(stream); - assigns *stream; - assigns *stream \from \nothing; +/*@ requires valid_name: valid_read_string(name); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, __fc_env[0 ..]; + assigns \result + \from __fc_env[0 ..], (indirect: name), (indirect: *(name + (0 ..))); + assigns __fc_env[0 ..] + \from __fc_env[0 ..], (indirect: name), (indirect: *(name + (0 ..))); */ -extern void clearerr_unlocked(FILE *stream); +int unsetenv(char const *name) +{ + int __retres; + char *tmp; + int tmp_2; + tmp = strchr(name,'='); + if (tmp) { + __retres = -1; + goto return_label; + } + size_t namelen = strlen(name); + if (namelen == (size_t)0) { + __retres = -1; + goto return_label; + } + __fc_initenv(); + tmp_2 = Frama_C_nondet(0,1); + if (tmp_2) { + int tmp_1; + tmp_1 = Frama_C_interval(0,4096 - 1); + __fc_env[tmp_1] = (char *)0; + } + __retres = 0; + return_label: return __retres; +} -/*@ requires valid_stream: \valid(stream); - assigns \result; - assigns \result \from (indirect: *stream); +/*@ requires valid_memptr: \valid(memptr); + requires + alignment_is_a_suitable_power_of_two: + alignment ≥ sizeof(void *) ∧ + ((size_t)alignment & (size_t)alignment - 1) ≡ 0; + assigns __fc_heap_status, \result; + assigns __fc_heap_status + \from (indirect: alignment), size, __fc_heap_status; + assigns \result + \from (indirect: alignment), (indirect: size), + (indirect: __fc_heap_status); + allocates *\old(memptr); + + behavior allocation: + assumes can_allocate: is_allocable(size); + ensures allocation: \fresh{Old, Here}(*\old(memptr),\old(size)); + ensures result_zero: \result ≡ 0; + assigns __fc_heap_status, \result; + assigns __fc_heap_status + \from (indirect: alignment), size, __fc_heap_status; + assigns \result + \from (indirect: alignment), (indirect: size), + (indirect: __fc_heap_status); + + behavior no_allocation: + assumes cannot_allocate: ¬is_allocable(size); + ensures result_non_zero: \result < 0 ∨ \result > 0; + assigns \result; + assigns \result \from (indirect: alignment); + allocates \nothing; + + complete behaviors no_allocation, allocation; + disjoint behaviors no_allocation, allocation; */ -extern int feof_unlocked(FILE *stream); +int posix_memalign(void **memptr, size_t alignment, size_t size) +{ + int __retres; + /*@ + assert + alignment_is_a_suitable_power_of_two: + alignment ≥ sizeof(void *) ∧ + ((size_t)alignment & (size_t)alignment - 1) ≡ 0; + */ + ; + *memptr = malloc(size); + if (! *memptr) { + __retres = 12; + goto return_label; + } + __retres = 0; + return_label: return __retres; +} + +char *realpath(char const * restrict file_name, char * restrict resolved_name) +{ + char *__retres; + int tmp; + if (! file_name) { + __fc_errno = 22; + __retres = (char *)0; + goto return_label; + } + tmp = Frama_C_interval(0,6); + switch (tmp) { + case 0: __fc_errno = 13; + __retres = (char *)0; + goto return_label; + case 1: __fc_errno = 5; + __retres = (char *)0; + goto return_label; + case 2: __fc_errno = 40; + __retres = (char *)0; + goto return_label; + case 3: __fc_errno = 36; + __retres = (char *)0; + goto return_label; + case 4: __fc_errno = 2; + __retres = (char *)0; + goto return_label; + case 5: __fc_errno = 20; + __retres = (char *)0; + goto return_label; + default: break; + } + int realpath_len = Frama_C_interval(1,256); + if (! resolved_name) { + resolved_name = (char *)malloc((size_t)256); + if (! resolved_name) { + __fc_errno = 12; + __retres = (char *)0; + goto return_label; + } + } + Frama_C_make_unknown(resolved_name,(size_t)realpath_len); + *(resolved_name + (realpath_len - 1)) = (char)'\000'; + __retres = resolved_name; + return_label: return __retres; +} -/*@ requires valid_stream: \valid(stream); - assigns \result; - assigns \result \from (indirect: *stream); - */ -extern int ferror_unlocked(FILE *stream); +char *canonicalize_file_name(char const *path) +{ + char *tmp; + tmp = realpath(path,(char *)0); + return tmp; +} -/*@ requires valid_stream: \valid(stream); - assigns \result; - assigns \result \from (indirect: *stream); +/*@ requires valid_dest: valid_or_empty(dest, n); + requires valid_src: valid_read_or_empty(src, n); + requires + separation: + \separated((char *)dest + (0 .. n - 1), (char *)src + (0 .. n - 1)); + ensures + copied_contents: + memcmp{Post, Pre}((char *)\old(dest), (char *)\old(src), \old(n)) ≡ + 0; + ensures result_ptr: \result ≡ \old(dest); + assigns *((char *)dest + (0 .. n - 1)), \result; + assigns *((char *)dest + (0 .. n - 1)) + \from *((char *)src + (0 .. n - 1)); + assigns \result \from dest; */ -extern int fileno_unlocked(FILE *stream); - -/*@ axiomatic pipe_streams { - predicate is_open_pipe{L}(FILE *stream) ; - - } +void *memcpy(void * restrict dest, void const * restrict src, size_t n) +{ + { + size_t i = (size_t)0; + /*@ loop invariant no_eva: 0 ≤ i ≤ n; + loop invariant + no_eva: + ∀ ℤ k; + 0 ≤ k < i ⇒ *((char *)dest + k) ≡ *((char *)src + k); + loop assigns i, *((char *)dest + (0 .. n - 1)); + loop variant n - i; + */ + while (i < n) { + *((char *)dest + i) = *((char *)src + i); + i ++; + } + } + return dest; +} -*/ -/*@ requires valid_command: valid_read_string(command); - requires valid_type: valid_read_string(type); +/*@ requires valid_dest: valid_or_empty(dest, n); + requires valid_src: valid_read_or_empty(src, n); + requires + separation: + \separated((char *)dest + (0 .. n - 1), (char *)src + (0 .. n - 1)); ensures - result_error_or_valid_open_pipe: - \result ≡ \null ∨ - (\subset(\result, &__fc_fopen[0 .. 16 - 1]) ∧ is_open_pipe(\result)); - assigns \result, __fc_fopen[0 ..]; - assigns \result - \from (indirect: *command), (indirect: *type), __fc_p_fopen; - assigns __fc_fopen[0 ..] - \from (indirect: *command), (indirect: *type), __fc_fopen[0 ..]; + copied_contents: + memcmp{Post, Pre}((char *)\old(dest), (char *)\old(src), \old(n)) ≡ + 0; + ensures result_next_byte: \result ≡ \old(dest) + \old(n); + assigns *((char *)dest + (0 .. n - 1)), \result; + assigns *((char *)dest + (0 .. n - 1)) + \from *((char *)src + (0 .. n - 1)); + assigns \result \from dest, n; */ -extern FILE *popen(char const *command, char const *type); +void *mempcpy(void * restrict dest, void const * restrict src, size_t n) +{ + void *__retres; + size_t i; + i = (size_t)0; + /*@ loop invariant no_eva: 0 ≤ i ≤ n; + loop invariant + no_eva: + ∀ ℤ k; + 0 ≤ k < i ⇒ *((char *)dest + k) ≡ *((char *)src + k); + loop assigns i, *((char *)dest + (0 .. n - 1)); + loop variant n - i; + */ + while (i < n) { + *((char *)dest + i) = *((char *)src + i); + i ++; + } + __retres = (void *)((char *)dest + i); + return __retres; +} -/*@ requires valid_stream: \valid(stream); - requires open_pipe: is_open_pipe(stream); - ensures closed_stream: ¬is_open_pipe(\old(stream)); - assigns \result; - assigns \result \from (indirect: *stream); +/*@ assigns \result; + assigns \result \from (indirect: p), (indirect: q), (indirect: n); + + behavior separated: + assumes + separation: no_overlap: + \separated(p + (0 .. n - 1), q + (0 .. n - 1)); + ensures result_no_overlap: \result ≡ 0; + + behavior not_separated_lt: + assumes + separation: overlap: ¬\separated(p + (0 .. n - 1), q + (0 .. n - 1)); + assumes p_before_q: p ≤ q < p + n; + ensures result_p_before_q: \result ≡ -1; + + behavior not_separated_gt: + assumes + separation: overlap: ¬\separated(p + (0 .. n - 1), q + (0 .. n - 1)); + assumes p_after_q: q < p ≤ q + n; + ensures result_p_after_q: \result ≡ 1; + + complete behaviors not_separated_gt, not_separated_lt, separated; + disjoint behaviors not_separated_gt, not_separated_lt, separated; */ -extern int pclose(FILE *stream); - -ssize_t getline(char **lineptr, size_t *n, FILE *stream); - -FILE *fmemopen(void * restrict buf, size_t size, char const * restrict mode); - -int asprintf(char **strp, char const *fmt, void * const *__va_params); - -FILE __fc_initial_stdout = - {.__fc_FILE_id = (unsigned int)1, .__fc_FILE_data = 0U}; -FILE *__fc_stdout = & __fc_initial_stdout; -FILE __fc_initial_stderr = - {.__fc_FILE_id = (unsigned int)2, .__fc_FILE_data = 0U}; -FILE *__fc_stderr = & __fc_initial_stderr; -FILE __fc_initial_stdin = - {.__fc_FILE_id = (unsigned int)0, .__fc_FILE_data = 0U}; -FILE *__fc_stdin = & __fc_initial_stdin; -/*@ requires valid_mode: valid_read_string(mode); */ -static _Bool is_valid_mode(char const *mode) +static int memoverlap(char const *p, char const *q, size_t n) { - _Bool __retres; - if (! ((int)*(mode + 0) != 'r')) - if (! ((int)*(mode + 0) != 'w')) - if (! ((int)*(mode + 0) != 'a')) { - __retres = (_Bool)0; + int __retres; + uintptr_t p1 = (uintptr_t)p; + uintptr_t p2 = (uintptr_t)(p + n); + uintptr_t q1 = (uintptr_t)q; + uintptr_t q2 = (uintptr_t)(q + n); + if (p1 <= q1) { + if (p2 > q1) { + __retres = -1; + goto return_label; + } + else goto _LAND; + } + else { + _LAND: ; + if (q1 <= p1) + if (q2 > p1) { + __retres = 1; goto return_label; } - if (! *(mode + 1)) { - __retres = (_Bool)1; - goto return_label; - } - if (! ((int)*(mode + 1) != 'b')) - if (! ((int)*(mode + 1) != '+')) { - __retres = (_Bool)0; + else { + __retres = 0; + goto return_label; + } + else { + __retres = 0; goto return_label; } - if (! *(mode + 2)) { - __retres = (_Bool)1; - goto return_label; } - if ((int)*(mode + 2) == (int)*(mode + 1)) { - __retres = (_Bool)0; + return_label: return __retres; +} + +/*@ requires valid_dest: valid_or_empty(dest, n); + requires valid_src: valid_read_or_empty(src, n); + ensures + copied_contents: + memcmp{Post, Pre}((char *)\old(dest), (char *)\old(src), \old(n)) ≡ + 0; + ensures result_ptr: \result ≡ \old(dest); + assigns *((char *)dest + (0 .. n - 1)), \result; + assigns *((char *)dest + (0 .. n - 1)) + \from *((char *)src + (0 .. n - 1)); + assigns \result \from dest; + */ +void *memmove(void *dest, void const *src, size_t n) +{ + void *__retres; + int tmp; + if (n == (size_t)0) { + __retres = dest; goto return_label; } - else - if (! ((int)*(mode + 2) != 'b')) - if (! ((int)*(mode + 2) != '+')) { - __retres = (_Bool)0; - goto return_label; + char *s = (char *)src; + char *d = (char *)dest; + tmp = memoverlap((char const *)dest,(char const *)src,n); + if (tmp <= 0) { + size_t i = (size_t)0; + /*@ loop invariant no_eva: 0 ≤ i ≤ n; + loop invariant + no_eva: + ∀ ℤ k; + 0 ≤ k < i ⇒ + *((char *)dest + k) ≡ \at(*((char *)src + k),LoopEntry); + loop invariant + no_eva: + ∀ ℤ k; + i ≤ k < n ⇒ + *((char *)src + k) ≡ \at(*((char *)src + k),LoopEntry); + loop assigns i, *((char *)dest + (0 .. n - 1)); + loop variant n - i; + */ + while (i < n) { + *(d + i) = *(s + i); + i ++; + } + } + else { + { + size_t i_0 = n - (size_t)1; + /*@ loop invariant no_eva: 0 ≤ i_0 < n; + loop invariant + no_eva: + ∀ ℤ k; + i_0 < k < n ⇒ + *((char *)dest + k) ≡ \at(*((char *)src + k),LoopEntry); + loop invariant + no_eva: + ∀ ℤ k; + 0 ≤ k ≤ i_0 ⇒ + *((char *)src + k) ≡ \at(*((char *)src + k),LoopEntry); + loop assigns i_0, *((char *)dest + (0 .. n - 1)); + loop variant i_0; + */ + while (i_0 > (size_t)0) { + *(d + i_0) = *(s + i_0); + i_0 --; } - __retres = (_Bool)(! *(mode + 3)); + } + *(d + 0) = *(s + 0); + } + __retres = dest; return_label: return __retres; } -ssize_t getline(char **lineptr, size_t *n, FILE *stream) +/*@ requires valid_string_s: valid_read_string(s); + ensures acsl_c_equiv: \result ≡ strlen(\old(s)); + assigns \result; + assigns \result \from (indirect: *(s + (0 ..))); + */ +size_t strlen(char const *s) { - ssize_t __retres; - int tmp; - if (! lineptr) goto _LOR; - else - if (! n) goto _LOR; - else - if (! stream) { - _LOR: { - __fc_errno = 22; - __retres = -1; - goto return_label; - } - } - tmp = ferror(stream); - if (tmp) goto _LOR_0; - else { - int tmp_0; - tmp_0 = feof(stream); - if (tmp_0) { - _LOR_0: { - __retres = -1; - goto return_label; - } + size_t i; + i = (size_t)0; + while ((int)*(s + i) != 0) i ++; + return i; +} + +/*@ requires valid_string_s: valid_read_nstring(s, maxlen); + ensures + result_bounded: + \result ≡ strlen(\old(s)) ∨ \result ≡ \old(maxlen); + assigns \result; + assigns \result + \from (indirect: *(s + (0 .. maxlen - 1))), (indirect: maxlen); + */ +size_t strnlen(char const *s, size_t maxlen) +{ + size_t i; + i = (size_t)0; + while (1) { + if (i < maxlen) { + if (! ((int)*(s + i) != 0)) break; } + else break; + i ++; } - if (! *lineptr) goto _LOR_1; - else - if (*n == (size_t)0) { - _LOR_1: - { - *lineptr = (char *)malloc((size_t)2); - if (! lineptr) { - __fc_errno = 12; - __retres = -1; - goto return_label; - } - *n = (size_t)2; - } - } - size_t cur = (size_t)0; - while (1) { - int tmp_3; - tmp_3 = ferror(stream); - if (tmp_3) break; - else { - int tmp_4; - tmp_4 = feof(stream); - if (tmp_4) break; + return i; +} + +/*@ requires valid_s: valid_or_empty(s, n); + ensures + acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; + ensures result_ptr: \result ≡ \old(s); + assigns *((char *)s + (0 .. n - 1)), \result; + assigns *((char *)s + (0 .. n - 1)) \from c; + assigns \result \from s; + */ +void *memset(void *s, int c, size_t n) +{ + unsigned char *p = (unsigned char *)s; + { + size_t i = (size_t)0; + while (i < n) { + *(p + i) = (unsigned char)c; + i ++; } - { - while (cur < *n - (size_t)1) { - int tmp_1; - tmp_1 = fgetc(stream); - char c = (char)tmp_1; - if ((int)c == -1) - if (cur == (size_t)0) { - __retres = -1; - goto return_label; - } - if ((int)c != -1) { - size_t tmp_2; - tmp_2 = cur; - cur ++; - *(*lineptr + tmp_2) = c; - } - if ((int)c == '\n') goto _LOR_2; - else - if ((int)c == -1) { - _LOR_2: - { - *(*lineptr + cur) = (char)'\000'; - __retres = (ssize_t)cur; - goto return_label; - } - } - } - if (*n == (size_t)2147483647) { - __fc_errno = 75; - __retres = -1; - goto return_label; - } - size_t new_size = *n + (size_t)1; - *lineptr = (char *)realloc((void *)*lineptr,new_size); - if (! *lineptr) { - __fc_errno = 12; - __retres = -1; - goto return_label; - } - *n = new_size; + } + return s; +} + +/*@ requires valid_string_s1: valid_read_string(s1); + requires valid_string_s2: valid_read_string(s2); + ensures acsl_c_equiv: \result ≡ strcmp(\old(s1), \old(s2)); + assigns \result; + assigns \result + \from (indirect: *(s1 + (0 ..))), (indirect: *(s2 + (0 ..))); + */ +int strcmp(char const *s1, char const *s2) +{ + int __retres; + size_t i; + i = (size_t)0; + while ((int)*(s1 + i) == (int)*(s2 + i)) { + if ((int)*(s1 + i) == 0) { + __retres = 0; + goto return_label; } + i ++; } - __retres = -1; + __retres = (int)*((unsigned char *)s1 + i) - (int)*((unsigned char *)s2 + i); return_label: return __retres; } -/*@ requires valid_strp: \valid(strp); - requires valid_fmt: valid_read_string(fmt); - ensures result_error_or_written_byes: \result ≡ -1 ∨ \result ≥ 0; - assigns __fc_heap_status, \result, *strp; - assigns __fc_heap_status - \from (indirect: *(fmt + (0 ..))), __fc_heap_status; +/*@ requires valid_string_s1: valid_read_nstring(s1, n); + requires valid_string_s2: valid_read_nstring(s2, n); + ensures acsl_c_equiv: \result ≡ strncmp(\old(s1), \old(s2), \old(n)); + assigns \result; assigns \result - \from (indirect: *(fmt + (0 ..))), (indirect: __fc_heap_status); - assigns *strp \from *(fmt + (0 ..)), (indirect: __fc_heap_status); - allocates *\old(strp); + \from (indirect: *(s1 + (0 .. n - 1))), + (indirect: *(s2 + (0 .. n - 1))), (indirect: n); */ -int asprintf(char **strp, char const *fmt, void * const *__va_params) +int strncmp(char const *s1, char const *s2, size_t n) { int __retres; - va_list args; - int tmp; - args = __va_params; - tmp = Frama_C_interval(1,256); - size_t len = (size_t)tmp; - *strp = (char *)malloc(len); - if (! *strp) { - __retres = -1; - goto return_label; + { + size_t i = (size_t)0; + while (i < n) { + if ((int)*(s1 + i) != (int)*(s2 + i)) { + __retres = (int)*((unsigned char *)s1 + i) - (int)*((unsigned char *)s2 + i); + goto return_label; + } + if ((int)*(s1 + i) == 0) { + __retres = 0; + goto return_label; + } + i ++; + } } - Frama_C_make_unknown(*strp,len - 1U); - *(*strp + (len - 1U)) = (char)0; - __retres = (int)len; + __retres = 0; return_label: return __retres; } -/*@ requires - valid_or_null_buff: - buf ≡ \null ∨ \valid((char *)buf + (0 .. size - 1)); - requires valid_mode: valid_read_string(mode); - ensures - result_error_or_valid: - \result ≡ \null ∨ \result ∈ &__fc_fopen[0 .. 16 - 1]; +/*@ requires valid_s1: valid_read_or_empty(s1, n); + requires valid_s2: valid_read_or_empty(s2, n); + requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); + requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); + requires danglingness: s1: non_escaping(s1, n); + requires danglingness: s2: non_escaping(s2, n); ensures - errno_set: - __fc_errno ≡ \old(__fc_errno) ∨ __fc_errno ∈ {22, 24, 12}; - assigns __fc_errno, \result; - assigns __fc_errno - \from (indirect: buf), (indirect: size), - (indirect: *(mode + (0 .. strlen{Old}(mode)))); + logic_spec: + \result ≡ + memcmp{Pre, Pre}((char *)\old(s1), (char *)\old(s2), \old(n)); + assigns \result; assigns \result - \from __fc_p_fopen, (indirect: buf), (indirect: size), - (indirect: *(mode + (0 .. strlen{Old}(mode)))); - allocates \old(buf); + \from (indirect: *((char *)s1 + (0 .. n - 1))), + (indirect: *((char *)s2 + (0 .. n - 1))); */ -FILE *fmemopen(void * restrict buf, size_t size, char const * restrict mode) +int memcmp(void const *s1, void const *s2, size_t n) { - FILE *__retres; - _Bool tmp; - int tmp_1; - int tmp_2; - tmp = is_valid_mode(mode); - if (! tmp) { - __fc_errno = 22; - __retres = (FILE *)0; - goto return_label; - } - if (! buf) { - if (size == (size_t)0) { - int tmp_0; - tmp_0 = Frama_C_interval(0,1); - if (tmp_0) { - __fc_errno = 22; - __retres = (FILE *)0; + int __retres; + unsigned char const *p1; + unsigned char const *p2; + p1 = (unsigned char const *)s1; + p2 = (unsigned char const *)s2; + { + size_t i = (size_t)0; + while (i < n) { + if ((int)*(p1 + i) != (int)*(p2 + i)) { + __retres = (int)*(p1 + i) - (int)*(p2 + i); goto return_label; } + i ++; } - if ((int)*(mode + 1) != '+') - if (*(mode + 1)) - if ((int)*(mode + 2) != '+') { - __fc_errno = 22; - __retres = (FILE *)0; - goto return_label; - } - buf = malloc(size); - if (! buf) { - __fc_errno = 12; - __retres = (FILE *)0; - goto return_label; - } - } - tmp_1 = Frama_C_interval(0,1); - if (tmp_1) { - __fc_errno = 24; - __retres = (FILE *)0; - goto return_label; } - tmp_2 = Frama_C_interval(0,16 - 1); - __retres = & __fc_fopen[tmp_2]; + __retres = 0; return_label: return __retres; } -/*@ requires abs_representable: i > -2147483647 - 1; - assigns \result; - assigns \result \from i; - - behavior negative: - assumes negative: i < 0; - ensures opposite_result: \result ≡ -\old(i); - - behavior nonnegative: - assumes nonnegative: i ≥ 0; - ensures same_result: \result ≡ \old(i); - - complete behaviors nonnegative, negative; - disjoint behaviors nonnegative, negative; - */ -int abs(int i) +static int char_equal_ignore_case(char c1, char c2) { int __retres; - if (i < 0) { - __retres = - i; + if ((int)c1 >= 'A') + if ((int)c1 <= 'Z') c1 = (char)((int)c1 - ('A' - 'a')); + if ((int)c2 >= 'A') + if ((int)c2 <= 'Z') c2 = (char)((int)c2 - ('A' - 'a')); + if ((int)c1 == (int)c2) { + __retres = 0; + goto return_label; + } + else { + __retres = (int)((unsigned char)c2) - (int)((unsigned char)c1); goto return_label; } - __retres = i; return_label: return __retres; } -/*@ requires valid_nptr: \valid_read(p); +/*@ requires valid_string_s1: valid_read_string(s1); + requires valid_string_s2: valid_read_string(s2); assigns \result; - assigns \result \from (indirect: p), (indirect: *(p + (0 ..))); + assigns \result + \from (indirect: *(s1 + (0 ..))), (indirect: *(s2 + (0 ..))); */ -int atoi(char const *p) +int strcasecmp(char const *s1, char const *s2) { int __retres; - int n; - int c; - int tmp_1; - int tmp_3; - int neg = 0; - unsigned char *up = (unsigned char *)p; - c = (int)*up; - tmp_1 = isdigit(c); - if (! tmp_1) { - int tmp_0; - while (1) { - int tmp; - tmp = isspace(c); - if (! tmp) break; - up ++; - c = (int)*up; + size_t i; + i = (size_t)0; + while (1) { + if ((int)*(s1 + i) != 0) { + if (! ((int)*(s2 + i) != 0)) break; } - switch (c) { - case '-': neg ++; - case '+': { /* sequence */ - up ++; - c = (int)*up; - } + else break; + { + int res = char_equal_ignore_case(*(s1 + i),*(s2 + i)); + if (res != 0) { + __retres = res; + goto return_label; + } } - tmp_0 = isdigit(c); - if (! tmp_0) { + i ++; + } + if ((int)*(s1 + i) == 0) { + if ((int)*(s2 + i) == 0) { __retres = 0; goto return_label; } + else goto _LAND; } - n = '0' - c; - while (1) { - int tmp_2; - up ++; - c = (int)*up; - tmp_2 = isdigit(c); - if (! tmp_2) break; - n *= 10; - n += '0' - c; + else { + _LAND: ; + if ((int)*(s1 + i) == 0) { + __retres = -1; + goto return_label; + } + else { + __retres = 1; + goto return_label; + } } - if (neg) tmp_3 = n; else tmp_3 = - n; - __retres = tmp_3; return_label: return __retres; } -/*@ assigns __fc_heap_status, \result; - assigns __fc_heap_status - \from (indirect: nmemb), (indirect: size), __fc_heap_status; - assigns \result - \from (indirect: nmemb), (indirect: size), (indirect: __fc_heap_status); - allocates \result; - - behavior allocation: - assumes can_allocate: is_allocable(nmemb * size); - ensures - allocation: \fresh{Old, Here}(\result,\old(nmemb) * \old(size)); - ensures - initialization: - \initialized((char *)\result + (0 .. \old(nmemb) * \old(size) - 1)); - ensures - zero_initialization: - \subset(*((char *)\result + (0 .. \old(nmemb) * \old(size) - 1)), - {0}); - - behavior no_allocation: - assumes cannot_allocate: ¬is_allocable(nmemb * size); - ensures null_result: \result ≡ \null; - assigns \result; - assigns \result \from \nothing; - allocates \nothing; - - complete behaviors no_allocation, allocation; - disjoint behaviors no_allocation, allocation; +/*@ requires valid_string_src: valid_read_string(src); + requires valid_string_dest: valid_string(dest); + requires room_string: \valid(dest + (0 .. strlen(dest) + strlen(src))); + ensures + sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); + ensures + initialization: dest: + \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); + ensures + dest_null_terminated: + *(\old(dest) + \old(strlen(dest) + strlen(src))) ≡ 0; + ensures result_ptr: \result ≡ \old(dest); + assigns *(dest + + (strlen{Old}(dest) .. strlen{Old}(dest) + strlen{Old}(src))), + \result; + assigns + *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + strlen{Old}(src))) + \from *(src + (0 .. strlen{Old}(src))); + assigns \result \from dest; */ -void *calloc(size_t nmemb, size_t size) +char *strcat(char *dest, char const *src) { - void *__retres; - size_t l = nmemb * size; - if (size != (size_t)0) - if (l / size != nmemb) { - __retres = (void *)0; - goto return_label; - } - char *p = malloc(l); - if (p) memset((void *)p,0,l); - __retres = (void *)p; - return_label: return __retres; + size_t i; + size_t n = strlen((char const *)dest); + i = (size_t)0; + while ((int)*(src + i) != 0) { + *(dest + (n + i)) = *(src + i); + i ++; + } + *(dest + (n + i)) = (char)0; + return dest; } -static char __fc_env_strings[64]; -static char __fc_initenv_init; -static void __fc_initenv(void) -{ - if (! __fc_initenv_init) { - Frama_C_make_unknown(__fc_env_strings,(size_t)(64 - 1)); - { - int i = 0; - while (i < 4096) { - { - int tmp; - tmp = Frama_C_interval(0,64 - 1); - __fc_env[i] = & __fc_env_strings[tmp]; - } - i ++; - } - } - __fc_initenv_init = (char)1; +/*@ requires valid_nstring_src: valid_read_nstring(src, n); + requires valid_string_dest: valid_string(dest); + ensures result_ptr: \result ≡ \old(dest); + assigns *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + n)), \result; + assigns *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + n)) + \from *(src + (0 .. n)); + assigns \result \from dest; + + behavior complete: + assumes + valid_string_src_fits: valid_read_string(src) ∧ strlen(src) ≤ n; + requires + room_string: \valid((dest + strlen(dest)) + (0 .. strlen(src))); + ensures + sum_of_lengths: + strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); + assigns *(dest + + (strlen{Old}(dest) .. strlen{Old}(dest) + strlen{Old}(src))), + \result; + assigns + *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + strlen{Old}(src))) + \from *(src + (0 .. strlen{Old}(src))); + assigns \result \from dest; + + behavior partial: + assumes + valid_string_src_too_large: + ¬(valid_read_string(src) ∧ strlen(src) ≤ n); + requires room_string: \valid((dest + strlen(dest)) + (0 .. n)); + ensures + sum_of_bounded_lengths: + strlen(\old(dest)) ≡ \old(strlen(dest)) + \old(n); + assigns *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + n)), + \result; + assigns *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + n)) + \from *(src + (0 .. strlen{Old}(src))); + assigns \result \from dest; + */ +char *strncat(char *dest, char const *src, size_t n) +{ + size_t i; + size_t dest_len = strlen((char const *)dest); + i = (size_t)0; + while (i < n) { + if ((int)*(src + i) == 0) break; + *(dest + (dest_len + i)) = *(src + i); + i ++; } - return; + *(dest + (dest_len + i)) = (char)0; + return dest; } -/*@ requires valid_name: valid_read_string(name); - ensures null_or_valid_result: \result ≡ \null ∨ \valid(\result); - assigns \result; - assigns \result \from __fc_env[0 ..], (indirect: name), *(name + (0 ..)); +/*@ requires valid_string_src: valid_read_string(src); + requires room_string: \valid(dest + (0 .. strlen(src))); + requires + separation: + \separated(dest + (0 .. strlen(src)), src + (0 .. strlen(src))); + ensures equal_contents: strcmp(\old(dest), \old(src)) ≡ 0; + ensures result_ptr: \result ≡ \old(dest); + assigns *(dest + (0 .. strlen{Old}(src))), \result; + assigns *(dest + (0 .. strlen{Old}(src))) + \from *(src + (0 .. strlen{Old}(src))); + assigns \result \from dest; */ -char *getenv(char const *name) +char *strcpy(char *dest, char const *src) { - char *__retres; - int tmp_0; - /*@ assert ¬(strchr(name, '=') ≡ \true); */ ; - __fc_initenv(); - tmp_0 = Frama_C_nondet(0,1); - if (tmp_0) { - int tmp; - tmp = Frama_C_interval(0,4096 - 1); - ; - __retres = __fc_env[tmp]; - goto return_label; - } - else { - __retres = (char *)0; - goto return_label; + size_t i; + i = (size_t)0; + while ((int)*(src + i) != 0) { + *(dest + i) = *(src + i); + i ++; } - return_label: return __retres; + *(dest + i) = (char)0; + return dest; } -/*@ requires valid_string: valid_read_string(string); - assigns __fc_env[0 ..], \result; - assigns __fc_env[0 ..] \from __fc_env[0 ..], string; - assigns \result \from (indirect: __fc_env[0 ..]), (indirect: string); +/*@ requires valid_string_src: valid_read_string(src); + requires room_string: \valid(dest + (0 .. strlen(src))); + requires + separation: + \separated(dest + (0 .. strlen(src)), src + (0 .. strlen(src))); + ensures equal_contents: strcmp(\old(dest), \old(src)) ≡ 0; + ensures points_to_end: \result ≡ \old(dest) + strlen(\old(dest)); + assigns *(dest + (0 .. strlen{Old}(src))), \result; + assigns *(dest + (0 .. strlen{Old}(src))) + \from *(src + (0 .. strlen{Old}(src))); + assigns \result \from dest; */ -int putenv(char *string) +char *stpcpy(char *dest, char const *src) { - int __retres; - int tmp_3; - char *separator __attribute__((__unused__)) = - strchr((char const *)string,'='); - /*@ assert string_contains_separator: separator ≢ \null; */ ; - /*@ assert name_is_not_empty: separator ≢ string; */ ; - __fc_initenv(); - tmp_3 = Frama_C_nondet(0,1); - if (tmp_3) { - int tmp_1; - int tmp_2; - tmp_1 = Frama_C_nondet(0,1); - if (tmp_1) { - int tmp_0; - tmp_0 = Frama_C_interval(-2147483647 - 1,2147483647); - __retres = tmp_0; - goto return_label; - } - tmp_2 = Frama_C_interval(0,4096 - 1); - __fc_env[tmp_2] = string; + char *__retres; + size_t i; + i = (size_t)0; + while ((int)*(src + i) != 0) { + *(dest + i) = *(src + i); + i ++; } - __retres = 0; - return_label: return __retres; + *(dest + i) = (char)0; + __retres = dest + i; + return __retres; } -/*@ requires valid_name: valid_read_string(name); - requires valid_value: valid_read_string(value); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result, __fc_env[0 ..]; - assigns \result - \from __fc_env[0 ..], (indirect: name), (indirect: *(name + (0 ..))), - (indirect: value), (indirect: *(value + (0 ..))), - (indirect: overwrite); - assigns __fc_env[0 ..] - \from __fc_env[0 ..], (indirect: name), (indirect: *(name + (0 ..))), - (indirect: value), (indirect: *(value + (0 ..))), - (indirect: overwrite); +/*@ requires valid_nstring_src: valid_read_nstring(src, n); + requires room_nstring: \valid(dest + (0 .. n - 1)); + requires separation: \separated(dest + (0 .. n - 1), src + (0 .. n - 1)); + ensures result_ptr: \result ≡ \old(dest); + ensures initialization: \initialized(\old(dest) + (0 .. \old(n) - 1)); + assigns *(dest + (0 .. n - 1)), \result; + assigns *(dest + (0 .. n - 1)) \from *(src + (0 .. n - 1)); + assigns \result \from dest; + + behavior complete: + assumes src_fits: strlen(src) < n; + ensures equal_after_copy: strcmp(\old(dest), \old(src)) ≡ 0; + + behavior partial: + assumes src_too_long: n ≤ strlen(src); + ensures + equal_prefix: + memcmp{Post, Post}(\old(dest), \old(src), \old(n)) ≡ 0; */ -int setenv(char const *name, char const *value, int overwrite) +char *strncpy(char *dest, char const *src, size_t n) { - int __retres; - char *tmp; - int tmp_4; - tmp = strchr(name,'='); - if (tmp) { - __retres = -1; - goto return_label; - } - size_t namelen = strlen(name); - if (namelen == (size_t)0) { - __retres = -1; - goto return_label; - } - __fc_initenv(); - tmp_4 = Frama_C_nondet(0,1); - if (tmp_4) { - __retres = -1; - goto return_label; + size_t i; + i = (size_t)0; + while (i < n) { + *(dest + i) = *(src + i); + if ((int)*(src + i) == 0) break; + i ++; } - else { - int tmp_1; - int tmp_2; - int tmp_3; - tmp_1 = Frama_C_nondet(0,1); - if (tmp_1) Frama_C_make_unknown(__fc_env_strings,(size_t)(64 - 1)); - tmp_2 = Frama_C_interval(0,4096 - 1); - tmp_3 = Frama_C_interval(0,64 - 1); - __fc_env[tmp_2] = & __fc_env_strings[tmp_3]; - __retres = 0; - goto return_label; + while (i < n) { + *(dest + i) = (char)0; + i ++; } - return_label: return __retres; + return dest; } -/*@ requires valid_name: valid_read_string(name); - ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; - assigns \result, __fc_env[0 ..]; +/*@ requires valid_string_s: valid_read_string(s); + assigns \result; assigns \result - \from __fc_env[0 ..], (indirect: name), (indirect: *(name + (0 ..))); - assigns __fc_env[0 ..] - \from __fc_env[0 ..], (indirect: name), (indirect: *(name + (0 ..))); + \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); + + behavior found: + assumes char_found: strchr(s, c) ≡ \true; + ensures result_char: *\result ≡ (char)\old(c); + ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); + ensures + result_in_length: \old(s) ≤ \result ≤ \old(s) + strlen(\old(s)); + ensures result_valid_string: valid_read_string(\result); + ensures + result_first_occur: + ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); + + behavior not_found: + assumes char_not_found: ¬(strchr(s, c) ≡ \true); + ensures result_null: \result ≡ \null; + + behavior default: + ensures + result_null_or_same_base: + \result ≡ \null ∨ \base_addr(\result) ≡ \base_addr(\old(s)); */ -int unsetenv(char const *name) +char *strchr(char const *s, int c) { - int __retres; - char *tmp; - int tmp_2; - tmp = strchr(name,'='); - if (tmp) { - __retres = -1; - goto return_label; - } - size_t namelen = strlen(name); - if (namelen == (size_t)0) { - __retres = -1; - goto return_label; + char *__retres; + size_t i; + char const ch = (char)c; + i = (size_t)0; + while ((int)*(s + i) != (int)ch) { + if ((int)*(s + i) == 0) { + __retres = (char *)0; + goto return_label; + } + i ++; } - __fc_initenv(); - tmp_2 = Frama_C_nondet(0,1); - if (tmp_2) { - int tmp_1; - tmp_1 = Frama_C_interval(0,4096 - 1); - __fc_env[tmp_1] = (char *)0; + __retres = (char *)(s + i); + return_label: return __retres; +} + +/*@ requires valid_string_s: valid_read_string(s); + assigns \result; + assigns \result \from s, *(s + (0 ..)), c; + + behavior found: + assumes char_found: strchr(s, c) ≡ \true; + ensures result_char: (int)*\result ≡ \old(c); + ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); + ensures result_valid_string: valid_read_string(\result); + + behavior not_found: + assumes char_not_found: ¬(strchr(s, c) ≡ \true); + ensures result_null: \result ≡ \null; + + behavior default: + ensures + result_null_or_same_base: + \result ≡ \null ∨ \base_addr(\result) ≡ \base_addr(\old(s)); + */ +char *strrchr(char const *s, int c) +{ + char *__retres; + char const ch = (char)c; + { + size_t tmp; + tmp = strlen(s); + size_t i = tmp + (size_t)1; + while (i > (size_t)0) { + if ((int)*(s + (i - (size_t)1)) == (int)ch) { + __retres = (char *)(s + (i - (size_t)1)); + goto return_label; + } + i --; + } } - __retres = 0; + __retres = (char *)0; return_label: return __retres; } -/*@ requires valid_memptr: \valid(memptr); +/*@ requires + valid: + valid_read_or_empty(s, n) ∨ + \valid_read((unsigned char *)s + (0 .. memchr_off((char *)s, c, n))); requires - alignment_is_a_suitable_power_of_two: - alignment ≥ sizeof(void *) ∧ - ((size_t)alignment & (size_t)alignment - 1) ≡ 0; - assigns __fc_heap_status, \result; - assigns __fc_heap_status - \from (indirect: alignment), size, __fc_heap_status; - assigns \result - \from (indirect: alignment), (indirect: size), - (indirect: __fc_heap_status); - allocates *\old(memptr); - - behavior allocation: - assumes can_allocate: is_allocable(size); - ensures allocation: \fresh{Old, Here}(*\old(memptr),\old(size)); - ensures result_zero: \result ≡ 0; - assigns __fc_heap_status, \result; - assigns __fc_heap_status - \from (indirect: alignment), size, __fc_heap_status; - assigns \result - \from (indirect: alignment), (indirect: size), - (indirect: __fc_heap_status); + initialization: + \initialized((unsigned char *)s + (0 .. n - 1)) ∨ + \initialized((unsigned char *)s + (0 .. memchr_off((char *)s, c, n))); + requires + danglingness: + non_escaping(s, n) ∨ + non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); + assigns \result; + assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); - behavior no_allocation: - assumes cannot_allocate: ¬is_allocable(size); - ensures result_non_zero: \result < 0 ∨ \result > 0; - assigns \result; - assigns \result \from (indirect: alignment); - allocates \nothing; + behavior found: + assumes char_found: memchr((char *)s, c, n) ≡ \true; + ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); + ensures result_char: (int)*((char *)\result) ≡ \old(c); + ensures + result_in_str: + ∀ ℤ i; + 0 ≤ i < \old(n) ⇒ + *((unsigned char *)\old(s) + i) ≡ \old(c) ⇒ + (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; - complete behaviors no_allocation, allocation; - disjoint behaviors no_allocation, allocation; + behavior not_found: + assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); + ensures result_null: \result ≡ \null; */ -int posix_memalign(void **memptr, size_t alignment, size_t size) +void *memchr(void const *s, int c, size_t n) { - int __retres; - /*@ - assert - alignment_is_a_suitable_power_of_two: - alignment ≥ sizeof(void *) ∧ - ((size_t)alignment & (size_t)alignment - 1) ≡ 0; - */ - ; - *memptr = malloc(size); - if (! *memptr) { - __retres = 12; - goto return_label; + void *__retres; + unsigned char const ch = (unsigned char)c; + unsigned char const *ss = (unsigned char const *)s; + { + size_t i = (size_t)0; + while (i < n) { + if ((int)*(ss + i) == (int)ch) { + __retres = (void *)(ss + i); + goto return_label; + } + i ++; + } } - __retres = 0; + __retres = (void *)0; return_label: return __retres; } -char *realpath(char const * restrict file_name, char * restrict resolved_name) +void *memrchr(void const *s, int c, size_t n) { - char *__retres; - int tmp; - if (! file_name) { - __fc_errno = 22; - __retres = (char *)0; - goto return_label; - } - tmp = Frama_C_interval(0,6); - switch (tmp) { - case 0: __fc_errno = 13; - __retres = (char *)0; - goto return_label; - case 1: __fc_errno = 5; - __retres = (char *)0; - goto return_label; - case 2: __fc_errno = 40; - __retres = (char *)0; - goto return_label; - case 3: __fc_errno = 36; - __retres = (char *)0; - goto return_label; - case 4: __fc_errno = 2; - __retres = (char *)0; - goto return_label; - case 5: __fc_errno = 20; - __retres = (char *)0; - goto return_label; - default: break; - } - int realpath_len = Frama_C_interval(1,256); - if (! resolved_name) { - resolved_name = (char *)malloc((size_t)256); - if (! resolved_name) { - __fc_errno = 12; - __retres = (char *)0; - goto return_label; + void *__retres; + unsigned char const ch = (unsigned char)c; + unsigned char const *ss = (unsigned char const *)s; + { + size_t i = n; + while (i > (size_t)0) { + if ((int)*(ss + (i - (size_t)1)) == (int)ch) { + __retres = (void *)(ss + (i - (size_t)1)); + goto return_label; + } + i --; } } - Frama_C_make_unknown(resolved_name,(size_t)realpath_len); - *(resolved_name + (realpath_len - 1)) = (char)'\000'; - __retres = resolved_name; + __retres = (void *)0; return_label: return __retres; } -char *canonicalize_file_name(char const *path) -{ - char *tmp; - tmp = realpath(path,(char *)0); - return tmp; -} - -/*@ requires valid_dest: valid_or_empty(dest, n); - requires valid_src: valid_read_or_empty(src, n); - requires - separation: - \separated((char *)dest + (0 .. n - 1), (char *)src + (0 .. n - 1)); +/*@ requires valid_string_haystack: valid_read_string(haystack); + requires valid_string_needle: valid_read_string(needle); ensures - copied_contents: - memcmp{Post, Pre}((char *)\old(dest), (char *)\old(src), \old(n)) ≡ - 0; - ensures result_ptr: \result ≡ \old(dest); - assigns *((char *)dest + (0 .. n - 1)), \result; - assigns *((char *)dest + (0 .. n - 1)) - \from *((char *)src + (0 .. n - 1)); - assigns \result \from dest; + result_null_or_in_haystack: + \result ≡ \null ∨ + (\subset(\result, \old(haystack) + (0 ..)) ∧ + \valid_read(\result) ∧ + memcmp{Pre, Pre}(\result, \old(needle), strlen(\old(needle))) ≡ 0); + assigns \result; + assigns \result + \from haystack, (indirect: *(haystack + (0 ..))), + (indirect: *(needle + (0 ..))); */ -void *memcpy(void * restrict dest, void const * restrict src, size_t n) +char *strstr(char const *haystack, char const *needle) { + char *__retres; + if ((int)*(needle + 0) == 0) { + __retres = (char *)haystack; + goto return_label; + } { size_t i = (size_t)0; - /*@ loop invariant no_eva: 0 ≤ i ≤ n; - loop invariant - no_eva: - ∀ ℤ k; - 0 ≤ k < i ⇒ *((char *)dest + k) ≡ *((char *)src + k); - loop assigns i, *((char *)dest + (0 .. n - 1)); - loop variant n - i; - */ - while (i < n) { - *((char *)dest + i) = *((char *)src + i); + while ((int)*(haystack + i) != 0) { + { + size_t j; + j = (size_t)0; + while ((int)*(haystack + (i + j)) != 0) { + if ((int)*(haystack + (i + j)) != (int)*(needle + j)) break; + j ++; + } + if ((int)*(needle + j) == 0) { + __retres = (char *)(haystack + i); + goto return_label; + } + } i ++; } } - return dest; + __retres = (char *)0; + return_label: return __retres; } -/*@ requires valid_dest: valid_or_empty(dest, n); - requires valid_src: valid_read_or_empty(src, n); - requires - separation: - \separated((char *)dest + (0 .. n - 1), (char *)src + (0 .. n - 1)); - ensures - copied_contents: - memcmp{Post, Pre}((char *)\old(dest), (char *)\old(src), \old(n)) ≡ - 0; - ensures result_next_byte: \result ≡ \old(dest) + \old(n); - assigns *((char *)dest + (0 .. n - 1)), \result; - assigns *((char *)dest + (0 .. n - 1)) - \from *((char *)src + (0 .. n - 1)); - assigns \result \from dest, n; +static int strerror___fc_strerror_init; +/*@ ensures result_internal_str: \result ≡ __fc_p_strerror; + ensures result_nul_terminated: *(\result + 63) ≡ 0; + ensures result_valid_string: valid_read_string(\result); + assigns \result; + assigns \result \from __fc_p_strerror, (indirect: errnum); */ -void *mempcpy(void * restrict dest, void const * restrict src, size_t n) +char *strerror(int errnum) { - void *__retres; - size_t i; - i = (size_t)0; - /*@ loop invariant no_eva: 0 ≤ i ≤ n; - loop invariant - no_eva: - ∀ ℤ k; - 0 ≤ k < i ⇒ *((char *)dest + k) ≡ *((char *)src + k); - loop assigns i, *((char *)dest + (0 .. n - 1)); - loop variant n - i; - */ - while (i < n) { - *((char *)dest + i) = *((char *)src + i); - i ++; + char *__retres; + if (! strerror___fc_strerror_init) { + Frama_C_make_unknown(__fc_strerror,(size_t)63); + __fc_strerror[63] = (char)0; + strerror___fc_strerror_init = 1; } - __retres = (void *)((char *)dest + i); + __retres = __fc_strerror; return __retres; } -/*@ assigns \result; - assigns \result \from (indirect: p), (indirect: q), (indirect: n); +/*@ requires valid_string_s: valid_read_string(s); + assigns \result; + assigns \result + \from (indirect: *(s + (0 .. strlen{Old}(s)))), + (indirect: __fc_heap_status); + allocates \result; - behavior separated: - assumes - separation: no_overlap: - \separated(p + (0 .. n - 1), q + (0 .. n - 1)); - ensures result_no_overlap: \result ≡ 0; + behavior allocation: + assumes can_allocate: is_allocable(strlen(s)); + ensures allocation: \fresh{Old, Here}(\result,strlen(\old(s))); + ensures + result_valid_string_and_same_contents: + valid_string(\result) ∧ strcmp(\result, \old(s)) ≡ 0; + assigns __fc_heap_status, \result; + assigns __fc_heap_status \from (indirect: s), __fc_heap_status; + assigns \result + \from (indirect: *(s + (0 .. strlen{Old}(s)))), + (indirect: __fc_heap_status); - behavior not_separated_lt: - assumes - separation: overlap: ¬\separated(p + (0 .. n - 1), q + (0 .. n - 1)); - assumes p_before_q: p ≤ q < p + n; - ensures result_p_before_q: \result ≡ -1; + behavior no_allocation: + assumes cannot_allocate: ¬is_allocable(strlen(s)); + ensures result_null: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; + */ +char *strdup(char const *s) +{ + char *__retres; + size_t tmp; + tmp = strlen(s); + size_t l = tmp + (size_t)1; + char *p = malloc(l); + if (! p) { + __fc_errno = 12; + __retres = (char *)0; + goto return_label; + } + memcpy((void *)p,(void const *)s,l); + __retres = p; + return_label: return __retres; +} + +/*@ requires valid_string_s: valid_read_string(s); + assigns \result; + assigns \result + \from (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: n), + (indirect: __fc_heap_status); + allocates \result; - behavior not_separated_gt: - assumes - separation: overlap: ¬\separated(p + (0 .. n - 1), q + (0 .. n - 1)); - assumes p_after_q: q < p ≤ q + n; - ensures result_p_after_q: \result ≡ 1; + behavior allocation: + assumes can_allocate: is_allocable(\min(strlen(s), n + 1)); + ensures + allocation: + \fresh{Old, Here}(\result,\min(strlen(\old(s)), \old(n) + 1)); + ensures + result_valid_string_bounded_and_same_prefix: + \valid(\result + (0 .. \min(strlen(\old(s)), \old(n)))) ∧ + valid_string(\result) ∧ strlen(\result) ≤ \old(n) ∧ + strncmp(\result, \old(s), \old(n)) ≡ 0; + assigns __fc_heap_status, \result; + assigns __fc_heap_status + \from (indirect: s), (indirect: n), __fc_heap_status; + assigns \result + \from (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: n), + (indirect: __fc_heap_status); - complete behaviors not_separated_gt, not_separated_lt, separated; - disjoint behaviors not_separated_gt, not_separated_lt, separated; + behavior no_allocation: + assumes cannot_allocate: ¬is_allocable(\min(strlen(s), n + 1)); + ensures result_null: \result ≡ \null; + assigns \result; + assigns \result \from \nothing; + allocates \nothing; */ -static int memoverlap(char const *p, char const *q, size_t n) +char *strndup(char const *s, size_t n) { - int __retres; - uintptr_t p1 = (uintptr_t)p; - uintptr_t p2 = (uintptr_t)(p + n); - uintptr_t q1 = (uintptr_t)q; - uintptr_t q2 = (uintptr_t)(q + n); - if (p1 <= q1) { - if (p2 > q1) { - __retres = -1; - goto return_label; - } - else goto _LAND; + char *__retres; + size_t l; + l = (size_t)0; + while (l < n) { + if ((int)*(s + l) == 0) break; + l ++; } - else { - _LAND: ; - if (q1 <= p1) - if (q2 > p1) { - __retres = 1; - goto return_label; - } - else { - __retres = 0; - goto return_label; - } - else { - __retres = 0; - goto return_label; - } + char *p = malloc(l + (size_t)1); + if (! p) { + __fc_errno = 12; + __retres = (char *)0; + goto return_label; } + memcpy((void *)p,(void const *)s,l); + *(p + l) = (char)0; + __retres = p; return_label: return __retres; } -/*@ requires valid_dest: valid_or_empty(dest, n); - requires valid_src: valid_read_or_empty(src, n); - ensures - copied_contents: - memcmp{Post, Pre}((char *)\old(dest), (char *)\old(src), \old(n)) ≡ - 0; - ensures result_ptr: \result ≡ \old(dest); - assigns *((char *)dest + (0 .. n - 1)), \result; - assigns *((char *)dest + (0 .. n - 1)) - \from *((char *)src + (0 .. n - 1)); - assigns \result \from dest; +static int strsignal___fc_strsignal_init; +/*@ ensures result_internal_str: \result ≡ __fc_p_strsignal; + ensures result_nul_terminated: *(\result + 63) ≡ 0; + ensures result_valid_string: valid_read_string(\result); + assigns \result; + assigns \result \from __fc_p_strsignal, (indirect: signum); */ -void *memmove(void *dest, void const *src, size_t n) +char *strsignal(int signum) { - void *__retres; - int tmp; - if (n == (size_t)0) { - __retres = dest; - goto return_label; - } - char *s = (char *)src; - char *d = (char *)dest; - tmp = memoverlap((char const *)dest,(char const *)src,n); - if (tmp <= 0) { - size_t i = (size_t)0; - /*@ loop invariant no_eva: 0 ≤ i ≤ n; - loop invariant - no_eva: - ∀ ℤ k; - 0 ≤ k < i ⇒ - *((char *)dest + k) ≡ \at(*((char *)src + k),LoopEntry); - loop invariant - no_eva: - ∀ ℤ k; - i ≤ k < n ⇒ - *((char *)src + k) ≡ \at(*((char *)src + k),LoopEntry); - loop assigns i, *((char *)dest + (0 .. n - 1)); - loop variant n - i; - */ - while (i < n) { - *(d + i) = *(s + i); - i ++; - } - } - else { - { - size_t i_0 = n - (size_t)1; - /*@ loop invariant no_eva: 0 ≤ i_0 < n; - loop invariant - no_eva: - ∀ ℤ k; - i_0 < k < n ⇒ - *((char *)dest + k) ≡ \at(*((char *)src + k),LoopEntry); - loop invariant - no_eva: - ∀ ℤ k; - 0 ≤ k ≤ i_0 ⇒ - *((char *)src + k) ≡ \at(*((char *)src + k),LoopEntry); - loop assigns i_0, *((char *)dest + (0 .. n - 1)); - loop variant i_0; - */ - while (i_0 > (size_t)0) { - *(d + i_0) = *(s + i_0); - i_0 --; - } - } - *(d + 0) = *(s + 0); + char *__retres; + if (! strsignal___fc_strsignal_init) { + Frama_C_make_unknown(__fc_strsignal,(size_t)63); + __fc_strsignal[63] = (char)0; + strsignal___fc_strsignal_init = 1; } - __retres = dest; - return_label: return __retres; + __retres = __fc_strsignal; + return __retres; } -/*@ requires valid_string_s: valid_read_string(s); - ensures acsl_c_equiv: \result ≡ strlen(\old(s)); +/*@ requires valid_string_path: valid_read_string(path); + requires valid_amode: (amode & ~((4 | 2) | 1)) ≡ 0 ∨ amode ≡ 0; + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result + \from (indirect: path), (indirect: *(path + (0 ..))), (indirect: amode); + */ +extern int access(char const *path, int amode); + +/*@ requires valid_string_path: valid_read_string(path); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: path), (indirect: *(path + (0 ..))); + */ +extern int chdir(char const *path); + +/*@ requires valid_string_path: valid_read_string(path); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: path), (indirect: *(path + (0 ..))); + */ +extern int chroot(char const *path); + +/*@ requires valid_string_path: valid_read_string(path); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result + \from (indirect: path), (indirect: *(path + (0 ..))), + (indirect: owner), (indirect: group); + */ +extern int chown(char const *path, uid_t owner, gid_t group); + +/*@ requires valid_fd: 0 ≤ fd < 1024; + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns __fc_fds[fd], \result; + assigns __fc_fds[fd] \from fd, __fc_fds[fd]; + assigns \result \from (indirect: fd), (indirect: __fc_fds[fd]); + */ +extern int close(int fd); + +/*@ requires valid_fildes: 0 ≤ fildes < 1024; + ensures + result_valid_fildes_or_error: + \result ≡ -1 ∨ (\old(fildes) ≤ \result < 1024); + assigns __fc_fds[fildes ..], \result; + assigns __fc_fds[fildes ..] \from fildes; + assigns \result \from fildes; + */ +extern int dup(int fildes); + +/*@ requires valid_fildes: 0 ≤ fildes < 1024; + requires valid_fildes2: 0 ≤ fildes2 < 1024; + ensures + result_fildes2_or_error: \result ≡ \old(fildes2) ∨ \result ≡ -1; + assigns __fc_fds[fildes2], \result; + assigns __fc_fds[fildes2] \from fildes, fildes2, __fc_fds[fildes2]; + assigns \result + \from fildes, fildes2, __fc_fds[fildes], __fc_fds[fildes2]; + */ +extern int dup2(int fildes, int fildes2); + +/*@ requires valid_string_path: valid_read_string(path); + requires valid_string_arg: valid_read_string(arg); assigns \result; - assigns \result \from (indirect: *(s + (0 ..))); + assigns \result \from *(path + (0 ..)), *(arg + (0 ..)); */ -size_t strlen(char const *s) -{ - size_t i; - i = (size_t)0; - while ((int)*(s + i) != 0) i ++; - return i; -} +extern int execl(char const *path, char const *arg, void * const *__va_params); -/*@ requires valid_string_s: valid_read_nstring(s, maxlen); - ensures - result_bounded: - \result ≡ strlen(\old(s)) ∨ \result ≡ \old(maxlen); +/*@ requires valid_string_path: valid_read_string(path); + requires valid_string_arg: valid_read_string(arg); assigns \result; - assigns \result - \from (indirect: *(s + (0 .. maxlen - 1))), (indirect: maxlen); + assigns \result \from *(path + (0 ..)), *(arg + (0 ..)); */ -size_t strnlen(char const *s, size_t maxlen) -{ - size_t i; - i = (size_t)0; - while (1) { - if (i < maxlen) { - if (! ((int)*(s + i) != 0)) break; - } - else break; - i ++; - } - return i; -} +extern int execle(char const *path, char const *arg, + void * const *__va_params); -/*@ requires valid_s: valid_or_empty(s, n); - ensures - acsl_c_equiv: memset((char *)\old(s), \old(c), \old(n)) ≡ \true; - ensures result_ptr: \result ≡ \old(s); - assigns *((char *)s + (0 .. n - 1)), \result; - assigns *((char *)s + (0 .. n - 1)) \from c; - assigns \result \from s; +/*@ requires valid_string_path: valid_read_string(path); + requires valid_string_arg: valid_read_string(arg); + assigns \result; + assigns \result \from *(path + (0 ..)), *(arg + (0 ..)); */ -void *memset(void *s, int c, size_t n) -{ - unsigned char *p = (unsigned char *)s; - { - size_t i = (size_t)0; - while (i < n) { - *(p + i) = (unsigned char)c; - i ++; - } - } - return s; -} +extern int execlp(char const *path, char const *arg, + void * const *__va_params); -/*@ requires valid_string_s1: valid_read_string(s1); - requires valid_string_s2: valid_read_string(s2); - ensures acsl_c_equiv: \result ≡ strcmp(\old(s1), \old(s2)); +/*@ requires valid_string_path: valid_read_string(path); + requires valid_string_argv0: valid_read_string(*(argv + 0)); assigns \result; - assigns \result - \from (indirect: *(s1 + (0 ..))), (indirect: *(s2 + (0 ..))); + assigns \result \from *(path + (0 ..)), *(argv + (0 ..)); */ -int strcmp(char const *s1, char const *s2) -{ - int __retres; - size_t i; - i = (size_t)0; - while ((int)*(s1 + i) == (int)*(s2 + i)) { - if ((int)*(s1 + i) == 0) { - __retres = 0; - goto return_label; - } - i ++; - } - __retres = (int)*((unsigned char *)s1 + i) - (int)*((unsigned char *)s2 + i); - return_label: return __retres; -} +extern int execv(char const *path, char * const *argv); -/*@ requires valid_string_s1: valid_read_nstring(s1, n); - requires valid_string_s2: valid_read_nstring(s2, n); - ensures acsl_c_equiv: \result ≡ strncmp(\old(s1), \old(s2), \old(n)); +/*@ requires valid_path: valid_read_string(path); + requires valid_argv0: valid_read_string(*(argv + 0)); assigns \result; - assigns \result - \from (indirect: *(s1 + (0 .. n - 1))), - (indirect: *(s2 + (0 .. n - 1))), (indirect: n); + assigns \result \from *(path + (0 ..)), *(argv + (0 ..)); */ -int strncmp(char const *s1, char const *s2, size_t n) -{ - int __retres; - { - size_t i = (size_t)0; - while (i < n) { - if ((int)*(s1 + i) != (int)*(s2 + i)) { - __retres = (int)*((unsigned char *)s1 + i) - (int)*((unsigned char *)s2 + i); - goto return_label; - } - if ((int)*(s1 + i) == 0) { - __retres = 0; - goto return_label; - } - i ++; - } - } - __retres = 0; - return_label: return __retres; -} +extern int execve(char const *path, char * const *argv, char * const *env); -/*@ requires valid_s1: valid_read_or_empty(s1, n); - requires valid_s2: valid_read_or_empty(s2, n); - requires initialization: s1: \initialized((char *)s1 + (0 .. n - 1)); - requires initialization: s2: \initialized((char *)s2 + (0 .. n - 1)); - requires danglingness: s1: non_escaping(s1, n); - requires danglingness: s2: non_escaping(s2, n); - ensures - logic_spec: - \result ≡ - memcmp{Pre, Pre}((char *)\old(s1), (char *)\old(s2), \old(n)); +/*@ requires valid_string_path: valid_read_string(path); + requires valid_string_argv0: valid_read_string(*(argv + 0)); + assigns \result; + assigns \result \from *(path + (0 ..)), *(argv + (0 ..)); + */ +extern int execvp(char const *path, char * const *argv); + +/*@ ensures never_terminates: \false; + assigns \nothing; */ +extern __attribute__((__noreturn__)) void _exit(int __x0); + +/*@ ensures + result_ok_child_or_error: + \result ≡ 0 ∨ \result > 0 ∨ \result ≡ -1; assigns \result; + assigns \result \from \nothing; + */ +extern pid_t fork(void); + +/*@ requires valid_buf: \valid(buf + (0 .. size - 1)); + ensures result_ok_or_error: \result ≡ \null ∨ \result ≡ \old(buf); + assigns *(buf + (0 .. size - 1)), \result; + assigns *(buf + (0 .. size - 1)) \from (indirect: buf), (indirect: size); + assigns \result \from buf, (indirect: size); + */ +extern char *getcwd(char *buf, size_t size); + +/*@ assigns \result; + assigns \result \from \nothing; */ +extern gid_t getegid(void); + +/*@ assigns \result; + assigns \result \from \nothing; */ +extern uid_t geteuid(void); + +/*@ assigns \result; + assigns \result \from \nothing; */ +extern gid_t getgid(void); + +extern char volatile __fc_hostname[64]; + +/*@ requires name_has_room: \valid(name + (0 .. len - 1)); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, *(name + (0 .. len - 1)); assigns \result - \from (indirect: *((char *)s1 + (0 .. n - 1))), - (indirect: *((char *)s2 + (0 .. n - 1))); + \from (indirect: __fc_hostname[0 .. len]), (indirect: len); + assigns *(name + (0 .. len - 1)) + \from (indirect: __fc_hostname[0 .. len]), (indirect: len); */ -int memcmp(void const *s1, void const *s2, size_t n) -{ - int __retres; - unsigned char const *p1; - unsigned char const *p2; - p1 = (unsigned char const *)s1; - p2 = (unsigned char const *)s2; - { - size_t i = (size_t)0; - while (i < n) { - if ((int)*(p1 + i) != (int)*(p2 + i)) { - __retres = (int)*(p1 + i) - (int)*(p2 + i); - goto return_label; - } - i ++; - } - } - __retres = 0; - return_label: return __retres; -} +extern int gethostname(char *name, size_t len); -static int char_equal_ignore_case(char c1, char c2) -{ - int __retres; - if ((int)c1 >= 'A') - if ((int)c1 <= 'Z') c1 = (char)((int)c1 - ('A' - 'a')); - if ((int)c2 >= 'A') - if ((int)c2 <= 'Z') c2 = (char)((int)c2 - ('A' - 'a')); - if ((int)c1 == (int)c2) { - __retres = 0; - goto return_label; - } - else { - __retres = (int)((unsigned char)c2) - (int)((unsigned char)c1); - goto return_label; - } - return_label: return __retres; -} +/*@ requires name_valid_string: valid_read_nstring(name, len); + requires bounded_len: len ≤ 64; + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns __fc_hostname[0 .. len], \result; + assigns __fc_hostname[0 .. len] + \from *(name + (0 .. len - 1)), (indirect: len); + assigns \result \from (indirect: __fc_hostname[0 .. len]); + */ +extern int sethostname(char const *name, size_t len); + +/*@ assigns \result; + assigns \result \from (indirect: pid); */ +extern pid_t getpgid(pid_t pid); + +/*@ assigns \result; + assigns \result \from \nothing; */ +extern pid_t getpgrp(void); + +/*@ assigns \result; + assigns \result \from \nothing; */ +extern pid_t getpid(void); + +/*@ assigns \result; + assigns \result \from \nothing; */ +extern pid_t getppid(void); -/*@ requires valid_string_s1: valid_read_string(s1); - requires valid_string_s2: valid_read_string(s2); +/*@ assigns \result; + assigns \result \from \nothing; */ +extern pid_t getsid(pid_t __x0); + +/*@ assigns \result; + assigns \result \from \nothing; */ +extern uid_t getuid(void); + +/*@ ensures result_true_or_false: \result ≡ 0 ∨ \result ≡ 1; + assigns \result; + assigns \result \from (indirect: fd), (indirect: __fc_fds[fd]); + */ +extern int isatty(int fd); + +/*@ requires valid_path: valid_read_string(path1); + requires valid_path: valid_read_string(path2); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns \result; assigns \result - \from (indirect: *(s1 + (0 ..))), (indirect: *(s2 + (0 ..))); + \from (indirect: *(path1 + (0 .. strlen{Old}(path1)))), + (indirect: *(path2 + (0 .. strlen{Old}(path2)))); */ -int strcasecmp(char const *s1, char const *s2) -{ - int __retres; - size_t i; - i = (size_t)0; - while (1) { - if ((int)*(s1 + i) != 0) { - if (! ((int)*(s2 + i) != 0)) break; - } - else break; - { - int res = char_equal_ignore_case(*(s1 + i),*(s2 + i)); - if (res != 0) { - __retres = res; - goto return_label; - } - } - i ++; - } - if ((int)*(s1 + i) == 0) { - if ((int)*(s2 + i) == 0) { - __retres = 0; - goto return_label; - } - else goto _LAND; - } - else { - _LAND: ; - if ((int)*(s1 + i) == 0) { - __retres = -1; - goto return_label; - } - else { - __retres = 1; - goto return_label; - } - } - return_label: return __retres; -} +extern int link(char const *path1, char const *path2); -/*@ requires valid_string_src: valid_read_string(src); - requires valid_string_dest: valid_string(dest); - requires room_string: \valid(dest + (0 .. strlen(dest) + strlen(src))); - ensures - sum_of_lengths: strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); - ensures - initialization: dest: - \initialized(\old(dest) + (0 .. \old(strlen(dest) + strlen(src)))); - ensures - dest_null_terminated: - *(\old(dest) + \old(strlen(dest) + strlen(src))) ≡ 0; - ensures result_ptr: \result ≡ \old(dest); - assigns *(dest + - (strlen{Old}(dest) .. strlen{Old}(dest) + strlen{Old}(src))), - \result; - assigns - *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + strlen{Old}(src))) - \from *(src + (0 .. strlen{Old}(src))); - assigns \result \from dest; +/*@ requires valid_fd: 0 ≤ fd < 1024; + requires valid_whence: whence ≡ 0 ∨ whence ≡ 1 ∨ whence ≡ 2; + ensures result_error_or_offset: \result ≡ -1 ∨ 0 ≤ \result; + assigns \result, __fc_fds[fd]; + assigns \result + \from (indirect: fd), (indirect: __fc_fds[fd]), (indirect: offset), + (indirect: whence); + assigns __fc_fds[fd] + \from (indirect: fd), __fc_fds[fd], (indirect: offset), + (indirect: whence); */ -char *strcat(char *dest, char const *src) -{ - size_t i; - size_t n = strlen((char const *)dest); - i = (size_t)0; - while ((int)*(src + i) != 0) { - *(dest + (n + i)) = *(src + i); - i ++; - } - *(dest + (n + i)) = (char)0; - return dest; -} +extern off_t lseek(int fd, off_t offset, int whence); -/*@ requires valid_nstring_src: valid_read_nstring(src, n); - requires valid_string_dest: valid_string(dest); - ensures result_ptr: \result ≡ \old(dest); - assigns *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + n)), \result; - assigns *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + n)) - \from *(src + (0 .. n)); - assigns \result \from dest; +/*@ requires valid_path: valid_read_string(path); + assigns \result; + assigns \result \from (indirect: *(path + (0 ..))), (indirect: name); + */ +extern long pathconf(char const *path, int name); + +/*@ requires valid_pipefd: \valid(pipefd + (0 .. 1)); + ensures initialization: pipefd: \initialized(\old(pipefd) + (0 .. 1)); + ensures valid_fd0: 0 ≤ *(\old(pipefd) + 0) < 1024; + ensures valid_fd1: 0 ≤ *(\old(pipefd) + 1) < 1024; + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns *(pipefd + (0 .. 1)), \result; + assigns *(pipefd + (0 .. 1)) \from (indirect: __fc_fds[0 ..]); + assigns \result \from (indirect: __fc_fds[0 ..]); + */ +extern int pipe(int pipefd[2]); + +/*@ requires valid_fd: 0 ≤ fd < 1024; + requires buf_has_room: \valid((char *)buf + (0 .. count - 1)); + assigns __fc_fds[fd], \result, *((char *)buf + (0 .. count - 1)); + assigns __fc_fds[fd] \from __fc_fds[fd]; + assigns \result \from (indirect: __fc_fds[fd]), (indirect: count); + assigns *((char *)buf + (0 .. count - 1)) + \from (indirect: __fc_fds[fd]), (indirect: count); - behavior complete: + behavior full_read: assumes - valid_string_src_fits: valid_read_string(src) ∧ strlen(src) ≤ n; - requires - room_string: \valid((dest + strlen(dest)) + (0 .. strlen(src))); + nondet_small_count: + Frama_C_entropy_source ≢ 0 ∧ count ≤ 2147483647; + ensures res_full: \result ≡ \old(count); ensures - sum_of_lengths: - strlen(\old(dest)) ≡ \old(strlen(dest) + strlen(src)); - assigns *(dest + - (strlen{Old}(dest) .. strlen{Old}(dest) + strlen{Old}(src))), - \result; - assigns - *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + strlen{Old}(src))) - \from *(src + (0 .. strlen{Old}(src))); - assigns \result \from dest; + res_init: initialization: + \initialized((char *)\old(buf) + (0 .. \old(count) - 1)); - behavior partial: + behavior large_read_implementation_defined: assumes - valid_string_src_too_large: - ¬(valid_read_string(src) ∧ strlen(src) ≤ n); - requires room_string: \valid((dest + strlen(dest)) + (0 .. n)); + nondet_large_count: + Frama_C_entropy_source ≢ 0 ∧ count > 2147483647; ensures - sum_of_bounded_lengths: - strlen(\old(dest)) ≡ \old(strlen(dest)) + \old(n); - assigns *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + n)), - \result; - assigns *(dest + (strlen{Old}(dest) .. strlen{Old}(dest) + n)) - \from *(src + (0 .. strlen{Old}(src))); - assigns \result \from dest; + res_init: initialization: + \initialized((char *)\old(buf) + (0 .. \old(count) - 1)); + + behavior partial_or_error: + assumes nondet: Frama_C_entropy_source ≡ 0; + ensures result_error_or_read_length: -1 ≤ \result < \old(count); + ensures + initialization: buf: + \initialized((char *)\old(buf) + (0 .. \result - 1)); + + complete behaviors partial_or_error, + large_read_implementation_defined, + full_read; + disjoint behaviors partial_or_error, + large_read_implementation_defined, + full_read; */ -char *strncat(char *dest, char const *src, size_t n) -{ - size_t i; - size_t dest_len = strlen((char const *)dest); - i = (size_t)0; - while (i < n) { - if ((int)*(src + i) == 0) break; - *(dest + (dest_len + i)) = *(src + i); - i ++; - } - *(dest + (dest_len + i)) = (char)0; - return dest; -} +extern ssize_t read(int fd, void *buf, size_t count); -/*@ requires valid_string_src: valid_read_string(src); - requires room_string: \valid(dest + (0 .. strlen(src))); - requires - separation: - \separated(dest + (0 .. strlen(src)), src + (0 .. strlen(src))); - ensures equal_contents: strcmp(\old(dest), \old(src)) ≡ 0; - ensures result_ptr: \result ≡ \old(dest); - assigns *(dest + (0 .. strlen{Old}(src))), \result; - assigns *(dest + (0 .. strlen{Old}(src))) - \from *(src + (0 .. strlen{Old}(src))); - assigns \result \from dest; +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: gid); */ -char *strcpy(char *dest, char const *src) -{ - size_t i; - i = (size_t)0; - while ((int)*(src + i) != 0) { - *(dest + i) = *(src + i); - i ++; - } - *(dest + i) = (char)0; - return dest; -} +extern int setegid(gid_t gid); + +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: uid); + */ +extern int seteuid(uid_t uid); + +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: gid); + */ +extern int setgid(gid_t gid); + +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: pid), (indirect: pgid); + */ +extern int setpgid(pid_t pid, pid_t pgid); + +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: rgid), (indirect: egid); + */ +extern int setregid(gid_t rgid, gid_t egid); + +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: ruid), (indirect: euid); + */ +extern int setreuid(uid_t ruid, uid_t euid); -/*@ requires valid_string_src: valid_read_string(src); - requires room_string: \valid(dest + (0 .. strlen(src))); - requires - separation: - \separated(dest + (0 .. strlen(src)), src + (0 .. strlen(src))); - ensures equal_contents: strcmp(\old(dest), \old(src)) ≡ 0; - ensures points_to_end: \result ≡ \old(dest) + strlen(\old(dest)); - assigns *(dest + (0 .. strlen{Old}(src))), \result; - assigns *(dest + (0 .. strlen{Old}(src))) - \from *(src + (0 .. strlen{Old}(src))); - assigns \result \from dest; +/*@ ensures result_pgid_or_error: \result ≡ -1 ∨ \result ≥ 0; + assigns \result; + assigns \result \from \nothing; */ -char *stpcpy(char *dest, char const *src) -{ - char *__retres; - size_t i; - i = (size_t)0; - while ((int)*(src + i) != 0) { - *(dest + i) = *(src + i); - i ++; - } - *(dest + i) = (char)0; - __retres = dest + i; - return __retres; -} +extern pid_t setsid(void); -/*@ requires valid_nstring_src: valid_read_nstring(src, n); - requires room_nstring: \valid(dest + (0 .. n - 1)); - requires separation: \separated(dest + (0 .. n - 1), src + (0 .. n - 1)); - ensures result_ptr: \result ≡ \old(dest); - ensures initialization: \initialized(\old(dest) + (0 .. \old(n) - 1)); - assigns *(dest + (0 .. n - 1)), \result; - assigns *(dest + (0 .. n - 1)) \from *(src + (0 .. n - 1)); - assigns \result \from dest; - - behavior complete: - assumes src_fits: strlen(src) < n; - ensures equal_after_copy: strcmp(\old(dest), \old(src)) ≡ 0; - - behavior partial: - assumes src_too_long: n ≤ strlen(src); - ensures - equal_prefix: - memcmp{Post, Post}(\old(dest), \old(src), \old(n)) ≡ 0; +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result; + assigns \result \from (indirect: uid); */ -char *strncpy(char *dest, char const *src, size_t n) -{ - size_t i; - i = (size_t)0; - while (i < n) { - *(dest + i) = *(src + i); - if ((int)*(src + i) == 0) break; - i ++; - } - while (i < n) { - *(dest + i) = (char)0; - i ++; - } - return dest; -} +extern int setuid(uid_t uid); -/*@ requires valid_string_s: valid_read_string(s); +/*@ ensures unslept: 0 ≤ \result ≤ \old(seconds); assigns \result; - assigns \result - \from s, (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: c); - - behavior found: - assumes char_found: strchr(s, c) ≡ \true; - ensures result_char: *\result ≡ (char)\old(c); - ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); - ensures - result_in_length: \old(s) ≤ \result ≤ \old(s) + strlen(\old(s)); - ensures result_valid_string: valid_read_string(\result); - ensures - result_first_occur: - ∀ char *p; \old(s) ≤ p < \result ⇒ *p ≢ (char)\old(c); - - behavior not_found: - assumes char_not_found: ¬(strchr(s, c) ≡ \true); - ensures result_null: \result ≡ \null; - - behavior default: - ensures - result_null_or_same_base: - \result ≡ \null ∨ \base_addr(\result) ≡ \base_addr(\old(s)); + assigns \result \from seconds; */ -char *strchr(char const *s, int c) -{ - char *__retres; - size_t i; - char const ch = (char)c; - i = (size_t)0; - while ((int)*(s + i) != (int)ch) { - if ((int)*(s + i) == 0) { - __retres = (char *)0; - goto return_label; - } - i ++; - } - __retres = (char *)(s + i); - return_label: return __retres; -} +extern unsigned int sleep(unsigned int seconds); -/*@ requires valid_string_s: valid_read_string(s); +/*@ assigns \nothing; */ +extern void sync(void); + +/*@ assigns \result; + assigns \result \from (indirect: name); */ +extern long sysconf(int name); + +char volatile __fc_ttyname[32]; +char volatile *__fc_p_ttyname = __fc_ttyname; +/*@ requires valid_fildes: 0 ≤ fildes < 1024; + ensures + result_name_or_null: \result ≡ __fc_p_ttyname ∨ \result ≡ \null; assigns \result; - assigns \result \from s, *(s + (0 ..)), c; - - behavior found: - assumes char_found: strchr(s, c) ≡ \true; - ensures result_char: (int)*\result ≡ \old(c); - ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); - ensures result_valid_string: valid_read_string(\result); - - behavior not_found: - assumes char_not_found: ¬(strchr(s, c) ≡ \true); - ensures result_null: \result ≡ \null; - - behavior default: - ensures - result_null_or_same_base: - \result ≡ \null ∨ \base_addr(\result) ≡ \base_addr(\old(s)); + assigns \result \from __fc_p_ttyname, (indirect: fildes); */ -char *strrchr(char const *s, int c) -{ - char *__retres; - char const ch = (char)c; - { - size_t tmp; - tmp = strlen(s); - size_t i = tmp + (size_t)1; - while (i > (size_t)0) { - if ((int)*(s + (i - (size_t)1)) == (int)ch) { - __retres = (char *)(s + (i - (size_t)1)); - goto return_label; - } - i --; - } - } - __retres = (char *)0; - return_label: return __retres; -} +extern char *ttyname(int fildes); -/*@ requires - valid: - valid_read_or_empty(s, n) ∨ - \valid_read((unsigned char *)s + (0 .. memchr_off((char *)s, c, n))); - requires - initialization: - \initialized((unsigned char *)s + (0 .. n - 1)) ∨ - \initialized((unsigned char *)s + (0 .. memchr_off((char *)s, c, n))); - requires - danglingness: - non_escaping(s, n) ∨ - non_escaping(s, (size_t)(memchr_off((char *)s, c, n) + 1)); +/*@ requires valid_string_path: valid_read_string(path); + ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns \result; - assigns \result \from s, c, *((unsigned char *)s + (0 .. n - 1)); - - behavior found: - assumes char_found: memchr((char *)s, c, n) ≡ \true; - ensures result_same_base: \base_addr(\result) ≡ \base_addr(\old(s)); - ensures result_char: (int)*((char *)\result) ≡ \old(c); - ensures - result_in_str: - ∀ ℤ i; - 0 ≤ i < \old(n) ⇒ - *((unsigned char *)\old(s) + i) ≡ \old(c) ⇒ - (unsigned char *)\result ≤ (unsigned char *)\old(s) + i; - - behavior not_found: - assumes char_not_found: ¬(memchr((char *)s, c, n) ≡ \true); - ensures result_null: \result ≡ \null; + assigns \result \from (indirect: *(path + (0 .. strlen{Old}(path)))); */ -void *memchr(void const *s, int c, size_t n) -{ - void *__retres; - unsigned char const ch = (unsigned char)c; - unsigned char const *ss = (unsigned char const *)s; - { - size_t i = (size_t)0; - while (i < n) { - if ((int)*(ss + i) == (int)ch) { - __retres = (void *)(ss + i); - goto return_label; - } - i ++; - } - } - __retres = (void *)0; - return_label: return __retres; -} +extern int unlink(char const *path); -void *memrchr(void const *s, int c, size_t n) -{ - void *__retres; - unsigned char const ch = (unsigned char)c; - unsigned char const *ss = (unsigned char const *)s; - { - size_t i = n; - while (i > (size_t)0) { - if ((int)*(ss + (i - (size_t)1)) == (int)ch) { - __retres = (void *)(ss + (i - (size_t)1)); - goto return_label; - } - i --; - } - } - __retres = (void *)0; - return_label: return __retres; -} +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; + assigns \result, Frama_C_entropy_source; + assigns \result + \from (indirect: usec), (indirect: Frama_C_entropy_source); + assigns Frama_C_entropy_source \from Frama_C_entropy_source; + */ +extern int usleep(useconds_t usec); + +/*@ requires valid_fd: 0 ≤ fd < 1024; + requires buf_has_room: \valid_read((char *)buf + (0 .. count - 1)); + ensures + result_error_or_written_bytes: + \result ≡ -1 ∨ (0 ≤ \result ≤ \old(count)); + assigns __fc_fds[fd], \result; + assigns __fc_fds[fd] + \from (indirect: fd), (indirect: count), __fc_fds[fd]; + assigns \result + \from (indirect: fd), (indirect: count), (indirect: __fc_fds[fd]); + */ +extern ssize_t write(int fd, void const *buf, size_t count); + +/*@ requires valid_ruid: \valid(ruid); + requires valid_euid: \valid(suid); + requires valid_suid: \valid(euid); + ensures + initialization: result_ok_or_error: + (\result ≡ 0 ∧ \initialized(\old(ruid)) ∧ + \initialized(\old(euid)) ∧ \initialized(\old(suid))) ∨ + \result ≡ -1; + assigns *ruid, *euid, *suid, \result; + assigns *ruid \from \nothing; + assigns *euid \from \nothing; + assigns *suid \from \nothing; + assigns \result + \from (indirect: ruid), (indirect: euid), (indirect: suid); + */ +int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); -/*@ requires valid_string_haystack: valid_read_string(haystack); - requires valid_string_needle: valid_read_string(needle); - ensures - result_null_or_in_haystack: - \result ≡ \null ∨ - (\subset(\result, \old(haystack) + (0 ..)) ∧ - \valid_read(\result) ∧ - memcmp{Pre, Pre}(\result, \old(needle), strlen(\old(needle))) ≡ 0); +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns \result; assigns \result - \from haystack, (indirect: *(haystack + (0 ..))), - (indirect: *(needle + (0 ..))); + \from (indirect: ruid), (indirect: euid), (indirect: suid); */ -char *strstr(char const *haystack, char const *needle) -{ - char *__retres; - if ((int)*(needle + 0) == 0) { - __retres = (char *)haystack; - goto return_label; - } - { - size_t i = (size_t)0; - while ((int)*(haystack + i) != 0) { - { - size_t j; - j = (size_t)0; - while ((int)*(haystack + (i + j)) != 0) { - if ((int)*(haystack + (i + j)) != (int)*(needle + j)) break; - j ++; - } - if ((int)*(needle + j) == 0) { - __retres = (char *)(haystack + i); - goto return_label; - } - } - i ++; - } - } - __retres = (char *)0; - return_label: return __retres; -} +int setresuid(uid_t ruid, uid_t euid, uid_t suid); -static int strerror___fc_strerror_init; -/*@ ensures result_internal_str: \result ≡ __fc_p_strerror; - ensures result_nul_terminated: *(\result + 63) ≡ 0; - ensures result_valid_string: valid_read_string(\result); - assigns \result; - assigns \result \from __fc_p_strerror, (indirect: errnum); +/*@ requires valid_rgid: \valid(rgid); + requires valid_egid: \valid(sgid); + requires valid_sgid: \valid(egid); + ensures + initialization: result_ok_or_error: + (\result ≡ 0 ∧ \initialized(\old(rgid)) ∧ + \initialized(\old(egid)) ∧ \initialized(\old(sgid))) ∨ + \result ≡ -1; + assigns *rgid, *egid, *sgid, \result; + assigns *rgid \from \nothing; + assigns *egid \from \nothing; + assigns *sgid \from \nothing; + assigns \result + \from (indirect: rgid), (indirect: egid), (indirect: sgid); */ -char *strerror(int errnum) -{ - char *__retres; - if (! strerror___fc_strerror_init) { - Frama_C_make_unknown(__fc_strerror,(size_t)63); - __fc_strerror[63] = (char)0; - strerror___fc_strerror_init = 1; - } - __retres = __fc_strerror; - return __retres; -} +int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); -/*@ requires valid_string_s: valid_read_string(s); +/*@ ensures result_ok_or_error: \result ≡ 0 ∨ \result ≡ -1; assigns \result; assigns \result - \from (indirect: *(s + (0 .. strlen{Old}(s)))), - (indirect: __fc_heap_status); - allocates \result; - - behavior allocation: - assumes can_allocate: is_allocable(strlen(s)); - ensures allocation: \fresh{Old, Here}(\result,strlen(\old(s))); - ensures - result_valid_string_and_same_contents: - valid_string(\result) ∧ strcmp(\result, \old(s)) ≡ 0; - assigns __fc_heap_status, \result; - assigns __fc_heap_status \from (indirect: s), __fc_heap_status; - assigns \result - \from (indirect: *(s + (0 .. strlen{Old}(s)))), - (indirect: __fc_heap_status); - - behavior no_allocation: - assumes cannot_allocate: ¬is_allocable(strlen(s)); - ensures result_null: \result ≡ \null; - assigns \result; - assigns \result \from \nothing; - allocates \nothing; + \from (indirect: rgid), (indirect: egid), (indirect: sgid); */ -char *strdup(char const *s) -{ - char *__retres; - size_t tmp; - tmp = strlen(s); - size_t l = tmp + (size_t)1; - char *p = malloc(l); - if (! p) { - __fc_errno = 12; - __retres = (char *)0; - goto return_label; - } - memcpy((void *)p,(void const *)s,l); - __retres = p; - return_label: return __retres; -} +int setresgid(gid_t rgid, gid_t egid, gid_t sgid); -/*@ requires valid_string_s: valid_read_string(s); - assigns \result; +char *optarg; +int optind; + +int opterr; + +extern int optopt; + +int getopt(int argc, char * const *argv, char const *optstring); + +int optind = 1; +int opterr = 1; +/*@ assigns \result, *optarg, optind, opterr, optopt; assigns \result - \from (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: n), - (indirect: __fc_heap_status); - allocates \result; - - behavior allocation: - assumes can_allocate: is_allocable(\min(strlen(s), n + 1)); - ensures - allocation: - \fresh{Old, Here}(\result,\min(strlen(\old(s)), \old(n) + 1)); - ensures - result_valid_string_bounded_and_same_prefix: - \valid(\result + (0 .. \min(strlen(\old(s)), \old(n)))) ∧ - valid_string(\result) ∧ strlen(\result) ≤ \old(n) ∧ - strncmp(\result, \old(s), \old(n)) ≡ 0; - assigns __fc_heap_status, \result; - assigns __fc_heap_status - \from (indirect: s), (indirect: n), __fc_heap_status; - assigns \result - \from (indirect: *(s + (0 .. strlen{Old}(s)))), (indirect: n), - (indirect: __fc_heap_status); - - behavior no_allocation: - assumes cannot_allocate: ¬is_allocable(\min(strlen(s), n + 1)); - ensures result_null: \result ≡ \null; - assigns \result; - assigns \result \from \nothing; - allocates \nothing; + \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); + assigns *optarg + \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); + assigns optind + \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); + assigns opterr + \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); + assigns optopt + \from argc, *(argv + (0 .. argc - 1)), *(optstring + (0 ..)); */ -char *strndup(char const *s, size_t n) +int getopt(int argc, char * const *argv, char const *optstring) { - char *__retres; - size_t l; - l = (size_t)0; - while (l < n) { - if ((int)*(s + l) == 0) break; - l ++; - } - char *p = malloc(l + (size_t)1); - if (! p) { - __fc_errno = 12; - __retres = (char *)0; + int __retres; + int tmp_0; + size_t tmp; + int tmp_2; + char tmp_1; + if (argc == 0) { + __retres = -1; goto return_label; } - memcpy((void *)p,(void const *)s,l); - *(p + l) = (char)0; - __retres = p; + optind = Frama_C_interval(1,argc - 1); + tmp = strlen((char const *)*(argv + optind)); + tmp_0 = Frama_C_interval(0,(int)(tmp - (size_t)1)); + ; + optarg = (char *)Frama_C_nondet_ptr((void *)0, + (void *)(*(argv + optind) + tmp_0)); + tmp_1 = Frama_C_char_interval((char)(-128),(char)127); + tmp_2 = Frama_C_nondet(-1,(int)tmp_1); + __retres = tmp_2; return_label: return __retres; } -static int strsignal___fc_strsignal_init; -/*@ ensures result_internal_str: \result ≡ __fc_p_strsignal; - ensures result_nul_terminated: *(\result + 63) ≡ 0; - ensures result_valid_string: valid_read_string(\result); - assigns \result; - assigns \result \from __fc_p_strsignal, (indirect: signum); - */ -char *strsignal(int signum) -{ - char *__retres; - if (! strsignal___fc_strsignal_init) { - Frama_C_make_unknown(__fc_strsignal,(size_t)63); - __fc_strsignal[63] = (char)0; - strsignal___fc_strsignal_init = 1; - } - __retres = __fc_strsignal; - return __retres; -} - /*@ requires valid_dest: valid_or_empty((void *)dest, (size_t)(sizeof(wchar_t) * n)); requires @@ -9315,6 +9511,55 @@ extern int stat(char const *pathname, struct stat *buf); assigns \result \from (indirect: cmask); */ extern mode_t umask(mode_t cmask); +/*@ assigns \result, *optarg, optind, opterr, optopt, + *((longopts + (0 ..))->flag); + assigns \result + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns *optarg + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns optind + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns opterr + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns optopt + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns *((longopts + (0 ..))->flag) + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + */ +extern int getopt_long(int argc, char * const *argv, char const *shortopts, + struct option const *longopts, int *longind); + +/*@ assigns \result, *optarg, optind, opterr, optopt, + *((longopts + (0 ..))->flag); + assigns \result + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns *optarg + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns optind + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns opterr + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns optopt + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + assigns *((longopts + (0 ..))->flag) + \from argc, *(argv + (0 .. argc - 1)), *(shortopts + (0 ..)), + *(longopts + (0 ..)); + */ +extern int getopt_long_only(int argc, char * const *argv, + char const *shortopts, + struct option const *longopts, int *longind); + /*@ assigns *(*(outbuf + (0 .. *outbytesleft - 1))), __fc_errno; assigns *(*(outbuf + (0 .. *outbytesleft - 1))) \from *(*(inbuf + (0 .. *inbytesleft - 1))); diff --git a/tests/libc/oracle/stdio_c.res.oracle b/tests/libc/oracle/stdio_c.res.oracle index 87610795caa3a32a698653b4bbc4173b5224d238..4a959d7c3665065f268feba5995e3e5d667c6a8e 100644 --- a/tests/libc/oracle/stdio_c.res.oracle +++ b/tests/libc/oracle/stdio_c.res.oracle @@ -39,17 +39,36 @@ [eva] Done for function feof [eva] computing for function fgetc <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] using specification for function fgetc -[eva] FRAMAC_SHARE/libc/stdio.c:84: - function fgetc: precondition 'valid_stream' got status valid. +[eva] computing for function Frama_C_interval <- fgetc <- getline <- main. + Called from FRAMAC_SHARE/libc/stdio.c:174. +[eva] using specification for function Frama_C_interval +[eva] FRAMAC_SHARE/libc/stdio.c:174: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgetc <- getline <- main. + Called from FRAMAC_SHARE/libc/stdio.c:185. +[eva] FRAMAC_SHARE/libc/stdio.c:185: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgetc <- getline <- main. + Called from FRAMAC_SHARE/libc/stdio.c:190. +[eva] FRAMAC_SHARE/libc/stdio.c:190: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_unsigned_char_interval <- fgetc <- getline <- + main. + Called from FRAMAC_SHARE/libc/stdio.c:193. +[eva] using specification for function Frama_C_unsigned_char_interval +[eva] FRAMAC_SHARE/libc/stdio.c:193: + function Frama_C_unsigned_char_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_unsigned_char_interval +[eva] Recording results for fgetc [eva] Done for function fgetc [eva:alarm] FRAMAC_SHARE/libc/stdio.c:90: Warning: out of bounds write. assert \valid(*lineptr + tmp_2); (tmp_2 from cur++) [eva] FRAMAC_SHARE/libc/stdio.c:83: starting to merge loop iterations -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc [eva] FRAMAC_SHARE/libc/stdio.c:104: Call to builtin realloc [eva] FRAMAC_SHARE/libc/stdio.c:104: function realloc: precondition 'freeable' got status valid. @@ -61,12 +80,8 @@ [eva] computing for function feof <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. [eva] Done for function feof -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc [eva] FRAMAC_SHARE/libc/stdio.c:104: Call to builtin realloc [eva] computing for function ferror <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. @@ -74,12 +89,8 @@ [eva] computing for function feof <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. [eva] Done for function feof -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc [eva] FRAMAC_SHARE/libc/stdio.c:104: Call to builtin realloc [eva] computing for function ferror <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. @@ -87,12 +98,8 @@ [eva] computing for function feof <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. [eva] Done for function feof -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc [eva] FRAMAC_SHARE/libc/stdio.c:104: Call to builtin realloc [eva] computing for function ferror <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. @@ -100,12 +107,8 @@ [eva] computing for function feof <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. [eva] Done for function feof -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc [eva] FRAMAC_SHARE/libc/stdio.c:104: Call to builtin realloc [eva] computing for function ferror <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. @@ -140,18 +143,10 @@ [eva] computing for function feof <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. [eva] Done for function feof -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc [eva] FRAMAC_SHARE/libc/stdio.c:104: Call to builtin realloc [eva] computing for function ferror <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. @@ -177,18 +172,10 @@ [eva] computing for function feof <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. [eva] Done for function feof -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc [eva] FRAMAC_SHARE/libc/stdio.c:104: Call to builtin realloc [eva] computing for function ferror <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. @@ -214,18 +201,10 @@ [eva] computing for function feof <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. [eva] Done for function feof -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc -[eva] computing for function fgetc <- getline <- main. - Called from FRAMAC_SHARE/libc/stdio.c:84. -[eva] Done for function fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc +[eva] FRAMAC_SHARE/libc/stdio.c:84: Reusing old results for call to fgetc [eva] FRAMAC_SHARE/libc/stdio.c:104: Call to builtin realloc [eva] computing for function ferror <- getline <- main. Called from FRAMAC_SHARE/libc/stdio.c:82. @@ -248,7 +227,6 @@ Called from stdio_c.c:28. [eva] computing for function Frama_C_interval <- asprintf <- main. Called from FRAMAC_SHARE/libc/stdio.c:123. -[eva] using specification for function Frama_C_interval [eva] FRAMAC_SHARE/libc/stdio.c:123: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval @@ -277,19 +255,19 @@ [eva] computing for function fmemopen <- main. Called from stdio_c.c:39. [eva] computing for function is_valid_mode <- fmemopen <- main. - Called from FRAMAC_SHARE/libc/stdio.c:140. + Called from FRAMAC_SHARE/libc/stdio.c:206. [eva] Recording results for is_valid_mode [eva] Done for function is_valid_mode -[eva] FRAMAC_SHARE/libc/stdio.c:158: Call to builtin malloc -[eva] FRAMAC_SHARE/libc/stdio.c:158: allocating variable __malloc_fmemopen_l158 +[eva] FRAMAC_SHARE/libc/stdio.c:224: Call to builtin malloc +[eva] FRAMAC_SHARE/libc/stdio.c:224: allocating variable __malloc_fmemopen_l224 [eva] computing for function Frama_C_interval <- fmemopen <- main. - Called from FRAMAC_SHARE/libc/stdio.c:166. -[eva] FRAMAC_SHARE/libc/stdio.c:166: + Called from FRAMAC_SHARE/libc/stdio.c:232. +[eva] FRAMAC_SHARE/libc/stdio.c:232: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva] computing for function Frama_C_interval <- fmemopen <- main. - Called from FRAMAC_SHARE/libc/stdio.c:171. -[eva] FRAMAC_SHARE/libc/stdio.c:171: + Called from FRAMAC_SHARE/libc/stdio.c:237. +[eva] FRAMAC_SHARE/libc/stdio.c:237: function Frama_C_interval: precondition 'order' got status valid. [eva] Done for function Frama_C_interval [eva] Recording results for fmemopen @@ -303,9 +281,104 @@ function fwrite: precondition 'valid_stream' got status valid. [eva] Done for function fwrite [eva] stdio_c.c:43: assertion got status valid. +[eva] computing for function getchar <- main. + Called from stdio_c.c:46. +[eva] computing for function fgetc <- getchar <- main. + Called from FRAMAC_SHARE/libc/stdio.c:198. +[eva] computing for function Frama_C_interval <- fgetc <- getchar <- main. + Called from FRAMAC_SHARE/libc/stdio.c:174. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgetc <- getchar <- main. + Called from FRAMAC_SHARE/libc/stdio.c:185. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgetc <- getchar <- main. + Called from FRAMAC_SHARE/libc/stdio.c:190. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_unsigned_char_interval <- fgetc <- getchar <- + main. + Called from FRAMAC_SHARE/libc/stdio.c:193. +[eva] Done for function Frama_C_unsigned_char_interval +[eva] Recording results for fgetc +[eva] Done for function fgetc +[eva] Recording results for getchar +[eva] Done for function getchar +[eva:alarm] stdio_c.c:47: Warning: check 'must_be_unknown' got status unknown. +[eva:alarm] stdio_c.c:48: Warning: check 'must_be_unknown' got status unknown. +[eva:alarm] stdio_c.c:49: Warning: assertion got status unknown. +[eva] stdio_c.c:50: Reusing old results for call to fgetc +[eva:alarm] stdio_c.c:51: Warning: check 'must_be_unknown' got status unknown. +[eva:alarm] stdio_c.c:52: Warning: check 'must_be_unknown' got status unknown. +[eva:alarm] stdio_c.c:53: Warning: assertion got status unknown. +[eva] computing for function fgets <- main. + Called from stdio_c.c:55. +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:136. +[eva] FRAMAC_SHARE/libc/stdio.c:136: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:147. +[eva] FRAMAC_SHARE/libc/stdio.c:147: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:154. +[eva] FRAMAC_SHARE/libc/stdio.c:154: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:160. +[eva] FRAMAC_SHARE/libc/stdio.c:160: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] FRAMAC_SHARE/libc/stdio.c:151: starting to merge loop iterations +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:154. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:160. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:154. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:160. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:154. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:160. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:154. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_interval <- fgets <- main. + Called from FRAMAC_SHARE/libc/stdio.c:160. +[eva] Done for function Frama_C_interval +[eva:alarm] FRAMAC_SHARE/libc/stdio.c:169: Warning: + out of bounds write. assert \valid(s + i); +[eva] Recording results for fgets +[eva] Done for function fgets +[eva:alarm] stdio_c.c:57: Warning: + assertion 'at_least_one_char' got status unknown. [eva] Recording results for main [eva] done for function main [eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function fgetc: + Frama_C_entropy_source ∈ [--..--] + __fc_errno ∈ [--..--] + __retres ∈ [-1..255] +[eva:final-states] Values at end of function fgets: + Frama_C_entropy_source ∈ [--..--] + __fc_errno ∈ [--..--] + i ∈ [0..9] + buf[0..8] ∈ [--..--] or UNINITIALIZED + [9] ∈ {0} or UNINITIALIZED + __retres ∈ {{ NULL ; &buf[0] }} +[eva:final-states] Values at end of function getchar: + Frama_C_entropy_source ∈ [--..--] + __fc_errno ∈ [--..--] [eva:final-states] Values at end of function is_valid_mode: __retres ∈ {1} [eva:final-states] Values at end of function asprintf: @@ -321,12 +394,12 @@ __fc_heap_status ∈ [--..--] Frama_C_entropy_source ∈ [--..--] __fc_errno ∈ [--..--] - buf ∈ {{ NULL ; (void *)&__malloc_fmemopen_l158 }} + buf ∈ {{ NULL ; (void *)&__malloc_fmemopen_l224 }} __retres ∈ {{ NULL ; &__fc_fopen + [0..120],0%8 }} [eva:final-states] Values at end of function getline: __fc_heap_status ∈ [--..--] + Frama_C_entropy_source ∈ [--..--] __fc_errno ∈ [--..--] - __fc_fopen[0..15] ∈ [--..--] cur ∈ [0..2147483647] line ∈ {{ NULL ; &__malloc_w_getline_l73[0] ; &__realloc_w_getline_l104[0] }} @@ -348,6 +421,10 @@ len ∈ [0..2147483647] total_len ∈ [--..--] read ∈ {-1} or UNINITIALIZED + c ∈ [-1..127] + buf[0..8] ∈ [--..--] or UNINITIALIZED + [9] ∈ {0} or UNINITIALIZED + r_1 ∈ {{ NULL ; &buf[0] }} __retres ∈ {0; 1} __malloc_w_getline_l73[0..1] ∈ [--..--] or UNINITIALIZED __realloc_w_getline_l104[0..2147483645] ∈ [--..--] or UNINITIALIZED diff --git a/tests/libc/oracle/unistd_c.res.oracle b/tests/libc/oracle/unistd_c.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..e4af50a77b1ccf38a5bda80be61d9e81b1e82fed --- /dev/null +++ b/tests/libc/oracle/unistd_c.res.oracle @@ -0,0 +1,61 @@ +[kernel] Parsing unistd_c.c (with preprocessing) +[eva] Analyzing a complete application starting at main +[eva] Computing initial state +[eva] Initial state computed +[eva:initial-state] Values of globals at initialization + +[eva] computing for function getopt <- main. + Called from unistd_c.c:6. +[eva] computing for function Frama_C_interval <- getopt <- main. + Called from FRAMAC_SHARE/libc/unistd.c:38. +[eva] using specification for function Frama_C_interval +[eva] FRAMAC_SHARE/libc/unistd.c:38: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] FRAMAC_SHARE/libc/unistd.c:39: Call to builtin strlen +[eva] FRAMAC_SHARE/libc/unistd.c:39: + function strlen: precondition 'valid_string_s' got status valid. +[eva] computing for function Frama_C_interval <- getopt <- main. + Called from FRAMAC_SHARE/libc/unistd.c:39. +[eva] FRAMAC_SHARE/libc/unistd.c:39: + function Frama_C_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_interval +[eva] computing for function Frama_C_nondet_ptr <- getopt <- main. + Called from FRAMAC_SHARE/libc/unistd.c:39. +[eva] using specification for function Frama_C_nondet_ptr +[eva] Done for function Frama_C_nondet_ptr +[eva] computing for function Frama_C_char_interval <- getopt <- main. + Called from FRAMAC_SHARE/libc/unistd.c:40. +[eva] using specification for function Frama_C_char_interval +[eva] FRAMAC_SHARE/libc/unistd.c:40: + function Frama_C_char_interval: precondition 'order' got status valid. +[eva] Done for function Frama_C_char_interval +[eva] computing for function Frama_C_nondet <- getopt <- main. + Called from FRAMAC_SHARE/libc/unistd.c:40. +[eva] using specification for function Frama_C_nondet +[eva] Done for function Frama_C_nondet +[eva] Recording results for getopt +[eva] Done for function getopt +[eva] Recording results for main +[eva] done for function main +[eva] ====== VALUES COMPUTED ====== +[eva:final-states] Values at end of function getopt: + Frama_C_entropy_source ∈ [--..--] + optarg ∈ + {{ NULL ; "-this" + {0; 1; 2; 3; 4} ; "is a" + {0; 1; 2; 3; 4} ; + "Test0" + {0; 1; 2; 3; 4} }} + optind ∈ {1; 2; 3} + __retres ∈ [-128..127] +[eva:final-states] Values at end of function main: + Frama_C_entropy_source ∈ [--..--] + optarg ∈ + {{ NULL ; "-this" + {0; 1; 2; 3; 4} ; "is a" + {0; 1; 2; 3; 4} ; + "Test0" + {0; 1; 2; 3; 4} }} + optind ∈ {1; 2; 3} + argc ∈ {4} + argv[0] ∈ {{ "program_name" }} + [1] ∈ {{ "-this" }} + [2] ∈ {{ "is a" }} + [3] ∈ {{ "Test0" }} + r ∈ [-128..127] + __retres ∈ {0}