From c689bfc5a962e86c4cb7cec2c67b0a9d63dd5630 Mon Sep 17 00:00:00 2001 From: Andre Maroneze <andre.maroneze@cea.fr> Date: Thu, 2 May 2024 14:39:01 +0200 Subject: [PATCH] [libc] add several assigns clauses and minor improvements --- share/compliance/nonstandard_identifiers.json | 8 + share/dune | 1 + share/libc/__fc_utmp_constants.h | 65 ++ share/libc/dirent.h | 64 +- share/libc/ifaddrs.h | 27 +- share/libc/locale.h | 6 +- share/libc/netdb.h | 126 +++- share/libc/pthread.h | 553 ++++++++++++++---- share/libc/pwd.h | 15 + share/libc/semaphore.h | 62 +- share/libc/signal.h | 5 + share/libc/spawn.h | 76 ++- share/libc/strings.h | 36 +- share/libc/utmp.h | 80 ++- share/libc/utmpx.h | 50 +- tests/libc/fc_libc.c | 1 + 16 files changed, 981 insertions(+), 194 deletions(-) create mode 100644 share/libc/__fc_utmp_constants.h diff --git a/share/compliance/nonstandard_identifiers.json b/share/compliance/nonstandard_identifiers.json index 86e2fa0eb0e..4f4072a4687 100644 --- a/share/compliance/nonstandard_identifiers.json +++ b/share/compliance/nonstandard_identifiers.json @@ -7,9 +7,16 @@ "error_at_line": {"header":"error.h"}, "error_message_count": {"header":"error.h"}, "error_one_per_line": {"header":"error.h"}, + "exit_status": {"header":"utmp.h"}, "facilitynames": {"header":"syslog.h"}, + "freeifaddrs": {"header":"ifaddrs.h"}, + "freeifmaddrs": {"header":"ifaddrs.h"}, + "getifaddrs": {"header":"ifaddrs.h"}, + "getifmaddrs": {"header":"ifaddrs.h"}, "getresgid": {"header":"unistd.h"}, "getresuid": {"header":"unistd.h"}, + "ifaddrs": {"header":"ifaddrs.h"}, + "ifmaddrs": {"header":"ifaddrs.h"}, "makedev": {"header":"sys/types.h"}, "option": {"header":"getopt.h"}, "prioritynames": {"header":"syslog.h"}, @@ -21,6 +28,7 @@ "strcspn": {"header":"string.h"}, "strlcat": {"header":"string.h"}, "strlcpy": {"header":"string.h"}, + "utmp": {"header":"tmp.h"}, "wcslcat": {"header":"wchar.h"}, "wcslcpy": {"header":"wchar.h"} } diff --git a/share/dune b/share/dune index 95125fc8c20..bdd583e6b68 100644 --- a/share/dune +++ b/share/dune @@ -137,6 +137,7 @@ (libc/__fc_runtime.c as libc/__fc_runtime.c) (libc/__fc_select.h as libc/__fc_select.h) (libc/__fc_string_axiomatic.h as libc/__fc_string_axiomatic.h) +(libc/__fc_utmp_constants.h as libc/__fc_utmp_constants.h) (libc/aio.h as libc/aio.h) (libc/alloca.h as libc/alloca.h) (libc/argz.c as libc/argz.c) diff --git a/share/libc/__fc_utmp_constants.h b/share/libc/__fc_utmp_constants.h new file mode 100644 index 00000000000..36e64981f35 --- /dev/null +++ b/share/libc/__fc_utmp_constants.h @@ -0,0 +1,65 @@ +/**************************************************************************/ +/* */ +/* This file is part of Frama-C. */ +/* */ +/* Copyright (C) 2007-2024 */ +/* CEA (Commissariat à l'énergie atomique et aux énergies */ +/* alternatives) */ +/* */ +/* you can redistribute it and/or modify it under the terms of the GNU */ +/* Lesser General Public License as published by the Free Software */ +/* Foundation, version 2.1. */ +/* */ +/* It is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Lesser General Public License for more details. */ +/* */ +/* See the GNU Lesser General Public License version 2.1 */ +/* for more details (enclosed in the file licenses/LGPLv2.1). */ +/* */ +/**************************************************************************/ + +#ifndef __FC_DEFINE_FC_UTMP_CONSTANTS +#define __FC_DEFINE_FC_UTMP_CONSTANTS +#include "features.h" +__PUSH_FC_STDLIB +__BEGIN_DECLS +#include "stdio.h" + +#define _PATH_UTMP "/var/run/utmp" +#define UTMP_FILE _PATH_UTMP +#define UTMP_FILENAME _PATH_UTMP +#define _PATH_WTMP "/var/log/wtmp" +#define WTMP_FILE _PATH_WTMP +#define WTMP_FILENAME _PATH_WTMP + +#define UT_LINESIZE 32 +#define UT_NAMESIZE 32 +#define UT_HOSTSIZE 256 + +#define EMPTY 0 +#define BOOT_TIME 2 +#define OLD_TIME 4 +#define NEW_TIME 3 +#define USER_PROCESS 7 +#define INIT_PROCESS 5 +#define LOGIN_PROCESS 6 +#define DEAD_PROCESS 8 + +#define ut_name ut_user +#ifndef _NO_UT_TIME +# define ut_time ut_tv.tv_sec +#endif +#define ut_xtime ut_tv.tv_sec +#define ut_addr ut_addr_v6[0] + +// represents the user accounting database, /var/run/utmp +extern FILE __fc_utmp; + +// represents the user accounting database, /var/run/wtmp +extern FILE __fc_wtmp; + +__END_DECLS +__POP_FC_STDLIB +#endif diff --git a/share/libc/dirent.h b/share/libc/dirent.h index 29b62b28e9b..6502d82e23f 100644 --- a/share/libc/dirent.h +++ b/share/libc/dirent.h @@ -51,7 +51,10 @@ typedef struct DIR { DIR __fc_opendir[__FC_FOPEN_MAX]; DIR* const __fc_p_opendir = __fc_opendir; -extern int alphasort(const struct dirent **, const struct dirent **); +/*@ + assigns \result \from indirect:*a[0..], indirect:*b[0..]; +*/ +extern int alphasort(const struct dirent **a, const struct dirent **b); /*@ requires dirp_valid_dir_stream: \subset(dirp,&__fc_opendir[0 .. __FC_FOPEN_MAX-1]); @@ -61,9 +64,18 @@ extern int alphasort(const struct dirent **, const struct dirent **); ensures err_or_closed_on_success: (\result == 0 && dirp->__fc_dir_inode == \null) || \result == -1; */ -extern int closedir(DIR *dirp); -extern int dirfd(DIR *); -extern DIR *fdopendir(int); +extern int closedir(DIR *dirp); + +/*@ + assigns \result \from *fd; +*/ +extern int dirfd(DIR *fd); + +/*@ + assigns \result \from __fc_p_opendir; + assigns __fc_opendir[0 .. __FC_FOPEN_MAX-1] \from __fc_opendir[0 .. __FC_FOPEN_MAX-1]; +*/ +extern DIR *fdopendir(int fd); /*@ assigns \result \from path[0..], __fc_p_opendir; @@ -74,7 +86,7 @@ extern DIR *fdopendir(int); ensures stream_positioned_on_success: \result != \null ==> \result->__fc_dir_inode != \null; */ -extern DIR *opendir(const char *path); +extern DIR *opendir(const char *path); /*@ requires dirp_valid_dir_stream: \subset(dirp, &__fc_opendir[0 .. __FC_FOPEN_MAX-1]); @@ -85,16 +97,40 @@ extern DIR *opendir(const char *path); */ extern struct dirent *readdir(DIR *dirp); -extern int readdir_r(DIR * dirp, struct dirent * entry, - struct dirent ** result); -extern void rewinddir(DIR *); -extern int scandir(const char *, struct dirent ***, - int (*)(const struct dirent *), - int (*)(const struct dirent **, - const struct dirent **)); +/*@ + assigns \result \from *dirp, __fc_p_opendir; + assigns *dirp \from *dirp; + assigns *entry \from *entry; + assigns *result \from entry; + assigns __fc_errno \from indirect:*dirp, indirect:*entry; +*/ +extern int readdir_r(DIR * dirp, struct dirent * entry, + struct dirent ** result); + +/*@ + assigns *dirp \from *dirp; +*/ +extern void rewinddir(DIR *dirp); + +/*@ + allocates *namelist; + assigns \result, *namelist + \from indirect:dir[0..], indirect:sel, indirect:compar; +*/ +extern int scandir(const char *dir, struct dirent ***namelist, + int (*sel)(const struct dirent *), + int (*compar)(const struct dirent **, + const struct dirent **)); -extern void seekdir(DIR *, long); -extern long telldir(DIR *); +/*@ + assigns *dirp \from *dirp, loc; +*/ +extern void seekdir(DIR *dirp, long loc); + +/*@ + assigns \result \from *dirp; +*/ +extern long telldir(DIR *dirp); diff --git a/share/libc/ifaddrs.h b/share/libc/ifaddrs.h index 47bea2299b9..3103c229785 100644 --- a/share/libc/ifaddrs.h +++ b/share/libc/ifaddrs.h @@ -57,10 +57,29 @@ struct ifmaddrs { struct sockaddr *ifma_lladdr; }; -extern int getifaddrs(struct ifaddrs **); -extern void freeifaddrs(struct ifaddrs *); -extern int getifmaddrs(struct ifmaddrs **); -extern void freeifmaddrs(struct ifmaddrs *); +/*@ + allocates *ifap; + assigns \result, *ifap \from \nothing; // missing: \from 'system interfaces' +*/ +extern int getifaddrs(struct ifaddrs **ifap); + +/*@ + frees ifa; + assigns \nothing; +*/ +extern void freeifaddrs(struct ifaddrs *ifa); + +/*@ + allocates *ifmap; + assigns \result, *ifmap \from \nothing; // missing: \from 'system interfaces' +*/ +extern int getifmaddrs(struct ifmaddrs **ifmap); + +/*@ + frees ifmp; + assigns \nothing; +*/ +extern void freeifmaddrs(struct ifmaddrs *ifmp); __END_DECLS diff --git a/share/libc/locale.h b/share/libc/locale.h index 4d5f79a8339..c5ad18e7f35 100644 --- a/share/libc/locale.h +++ b/share/libc/locale.h @@ -149,7 +149,11 @@ extern char *setlocale(int category, const char *locale); */ extern struct lconv *localeconv(void); -extern locale_t duplocale(locale_t); +/*@ + allocates \result; + assigns *\result \from *locobj; + */ +extern locale_t duplocale(locale_t locobj); extern void freelocale(locale_t); extern locale_t newlocale(int, const char *, locale_t); extern locale_t uselocale(locale_t); diff --git a/share/libc/netdb.h b/share/libc/netdb.h index 7a5457ec2b3..e726683764f 100644 --- a/share/libc/netdb.h +++ b/share/libc/netdb.h @@ -119,10 +119,32 @@ struct addrinfo # define EAI_SYSTEM -11 /* System error returned in `errno'. */ # define EAI_OVERFLOW -12 /* Argument buffer overflow. */ +// dummy data, used for assigns clauses +extern struct hostent __fc_dummy_hostent; +extern struct netent __fc_dummy_netent; +extern struct protoent __fc_dummy_protoent; +extern struct servent __fc_dummy_servent; + +/*@ + assigns __fc_dummy_hostent \from \nothing; +*/ extern void endhostent(void); + +/*@ + assigns __fc_dummy_netent \from \nothing; +*/ extern void endnetent(void); + +/*@ + assigns __fc_dummy_protoent \from \nothing; +*/ extern void endprotoent(void); + +/*@ + assigns __fc_dummy_servent \from \nothing; +*/ extern void endservent(void); + /*@ requires addrinfo_valid: \valid(addrinfo); frees addrinfo; assigns \nothing; @@ -178,32 +200,102 @@ extern int getaddrinfo( const struct addrinfo *restrict hints, struct addrinfo **restrict res); -extern struct hostent *gethostbyaddr(const void *, socklen_t, int); +/*@ + assigns \result \from &__fc_dummy_hostent; + assigns *\result \from __fc_dummy_hostent, len, type; +*/ +extern struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type); /*@ - allocates \result; - assigns *\result \from name[0 .. strlen(name)], Frama_C_entropy_source; - assigns Frama_C_entropy_source \from Frama_C_entropy_source; + assigns \result \from &__fc_dummy_hostent; + assigns *\result \from __fc_dummy_hostent, name[0..]; */ extern struct hostent *gethostbyname(const char *name); +/*@ + assigns \result \from &__fc_dummy_hostent; +*/ extern struct hostent *gethostent(void); -extern int getnameinfo(const struct sockaddr *restrict, socklen_t, - char *restrict, socklen_t, char *restrict, - socklen_t, int); -extern struct netent *getnetbyaddr(uint32_t, int); -extern struct netent *getnetbyname(const char *); + +/*@ + assigns \result, host[0..hostlen-1], serv[0..servlen-1] + \from ((char*)addr)[0..addrlen-1]; +*/ +extern int getnameinfo(const struct sockaddr *restrict addr, socklen_t addrlen, + char *restrict host, socklen_t hostlen, + char *restrict serv, socklen_t servlen, + int flags); + +/*@ + assigns \result \from &__fc_dummy_netent; + assigns __fc_dummy_netent \from __fc_dummy_netent, net, type; +*/ +extern struct netent *getnetbyaddr(uint32_t net, int type); + +/*@ + assigns \result \from &__fc_dummy_netent; + assigns __fc_dummy_netent \from __fc_dummy_netent, name[0..]; +*/ +extern struct netent *getnetbyname(const char *name); + +/*@ + assigns \result \from &__fc_dummy_netent; +*/ extern struct netent *getnetent(void); -extern struct protoent *getprotobyname(const char *); -extern struct protoent *getprotobynumber(int); + +/*@ + assigns \result \from &__fc_dummy_protoent; + assigns __fc_dummy_protoent \from __fc_dummy_protoent, name[0..]; +*/ +extern struct protoent *getprotobyname(const char *name); + +/*@ + assigns \result \from &__fc_dummy_protoent; + assigns __fc_dummy_protoent \from __fc_dummy_protoent, proto; +*/ +extern struct protoent *getprotobynumber(int proto); + +/*@ + assigns \result \from &__fc_dummy_protoent; +*/ extern struct protoent *getprotoent(void); -extern struct servent *getservbyname(const char *, const char *); -extern struct servent *getservbyport(int, const char *); + +/*@ + assigns \result \from &__fc_dummy_servent; + assigns __fc_dummy_servent \from __fc_dummy_servent, name[0..], proto[0..]; +*/ +extern struct servent *getservbyname(const char *name, const char *proto); + +/*@ + assigns \result \from &__fc_dummy_servent; + assigns __fc_dummy_servent \from __fc_dummy_servent, port, proto[0..]; +*/ +extern struct servent *getservbyport(int port, const char *proto); + +/*@ + assigns \result \from &__fc_dummy_servent; +*/ extern struct servent *getservent(void); -extern void sethostent(int); -extern void setnetent(int); -extern void setprotoent(int); -extern void setservent(int); + +/*@ + assigns __fc_dummy_hostent \from indirect:stayopen; +*/ +extern void sethostent(int stayopen); + +/*@ + assigns __fc_dummy_netent \from indirect:stayopen; +*/ +extern void setnetent(int stayopen); + +/*@ + assigns __fc_dummy_protoent \from indirect:stayopen; +*/ +extern void setprotoent(int stayopen); + +/*@ + assigns __fc_dummy_servent \from indirect:stayopen; +*/ +extern void setservent(int stayopen); __END_DECLS diff --git a/share/libc/pthread.h b/share/libc/pthread.h index 12bef61e469..4f3b40e01ba 100644 --- a/share/libc/pthread.h +++ b/share/libc/pthread.h @@ -132,43 +132,150 @@ enum __fc_pthread_mutex_pshared #include "__fc_define_size_t.h" #include "sched.h" -extern int pthread_attr_destroy(pthread_attr_t *); -extern int pthread_attr_getdetachstate(const pthread_attr_t *, int *); -extern int pthread_attr_getguardsize(const pthread_attr_t *restrict, - size_t *restrict); -extern int pthread_attr_getinheritsched(const pthread_attr_t *restrict, - int *restrict); -extern int pthread_attr_getschedparam(const pthread_attr_t *restrict, - struct sched_param *restrict); -extern int pthread_attr_getschedpolicy(const pthread_attr_t *restrict, - int *restrict); -extern int pthread_attr_getscope(const pthread_attr_t *restrict, - int *restrict); -extern int pthread_attr_getstack(const pthread_attr_t *restrict, - void **restrict, size_t *restrict); -extern int pthread_attr_getstacksize(const pthread_attr_t *restrict, - size_t *restrict); -extern int pthread_attr_init(pthread_attr_t *); -extern int pthread_attr_setdetachstate(pthread_attr_t *, int); -extern int pthread_attr_setguardsize(pthread_attr_t *, size_t); -extern int pthread_attr_setinheritsched(pthread_attr_t *, int); -extern int pthread_attr_setschedparam(pthread_attr_t *restrict, - const struct sched_param *restrict); -extern int pthread_attr_setschedpolicy(pthread_attr_t *, int); -extern int pthread_attr_setscope(pthread_attr_t *, int); -extern int pthread_attr_setstack(pthread_attr_t *, void *, size_t); -extern int pthread_attr_setstacksize(pthread_attr_t *, size_t); -extern int pthread_barrier_destroy(pthread_barrier_t *); -extern int pthread_barrier_init(pthread_barrier_t *restrict, - const pthread_barrierattr_t *restrict, - unsigned); -extern int pthread_barrier_wait(pthread_barrier_t *); -extern int pthread_barrierattr_destroy(pthread_barrierattr_t *); -extern int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict, - int *restrict); -extern int pthread_barrierattr_init(pthread_barrierattr_t *); -extern int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int); -extern int pthread_cancel(pthread_t); +/*@ + assigns \result, *attr \from *attr; +*/ +extern int pthread_attr_destroy(pthread_attr_t *attr); + +/*@ + assigns \result, *detachstate \from *attr; +*/ +extern int pthread_attr_getdetachstate(const pthread_attr_t *attr, + int *detachstate); + +/*@ + assigns \result, *guardsize \from *attr; +*/ +extern int pthread_attr_getguardsize(const pthread_attr_t *restrict attr, + size_t *restrict guardsize); + +/*@ + assigns \result, *inheritsched \from *attr; +*/ +extern int pthread_attr_getinheritsched(const pthread_attr_t *restrict attr, + int *restrict inheritsched); + +/*@ + assigns \result, *schedparam \from *attr; +*/ +extern int pthread_attr_getschedparam(const pthread_attr_t *restrict attr, + struct sched_param *restrict schedparam); + +/*@ + assigns \result, *schedpolicy \from *attr; +*/ +extern int pthread_attr_getschedpolicy(const pthread_attr_t *restrict attr, + int *restrict schedpolicy); + +/*@ + assigns \result, *contentionscope \from *attr; +*/ +extern int pthread_attr_getscope(const pthread_attr_t *restrict attr, + int *restrict contentionscope); + +/*@ + assigns \result, *stackaddr, *stacksize \from *attr; +*/ +extern int pthread_attr_getstack(const pthread_attr_t *restrict attr, + void **restrict stackaddr, + size_t *restrict stacksize); + +/*@ + assigns \result, *stacksize \from *attr; +*/ +extern int pthread_attr_getstacksize(const pthread_attr_t *restrict attr, + size_t *restrict stacksize); + +/*@ + assigns \result, *attr \from \nothing; +*/ +extern int pthread_attr_init(pthread_attr_t *attr); + +/*@ + assigns \result, *attr \from detachstate; +*/ +extern int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); + +/*@ + assigns \result, *attr \from guardsize; +*/ +extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); + +/*@ + assigns \result, *attr \from inheritsched; +*/ +extern int pthread_attr_setinheritsched(pthread_attr_t *attr, + int inheritsched); + +/*@ + assigns \result, *attr \from *attr, *schedparam; + */ +extern int pthread_attr_setschedparam(pthread_attr_t *restrict attr, + const struct sched_param *restrict schedparam); + +/*@ + assigns \result, *attr \from schedpolicy; +*/ +extern int pthread_attr_setschedpolicy(pthread_attr_t *attr, int schedpolicy); + +/*@ + assigns \result, *attr \from contentionscope; +*/ +extern int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope); + +/*@ + assigns \result, *attr \from stackaddr, stacksize; +*/ +extern int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, + size_t stacksize); + +/*@ + assigns \result, *attr \from stacksize; +*/ +extern int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); + +/*@ + assigns \result, *barrier \from *barrier; +*/ +extern int pthread_barrier_destroy(pthread_barrier_t *barrier); + +/*@ + assigns \result, *barrier \from *attr, count; +*/ +extern int pthread_barrier_init(pthread_barrier_t *restrict barrier, + const pthread_barrierattr_t *restrict attr, + unsigned count); + +/*@ + assigns \result, *barrier \from *barrier; +*/ +extern int pthread_barrier_wait(pthread_barrier_t *barrier); + +/*@ + assigns \result, *attr \from *attr; +*/ +extern int pthread_barrierattr_destroy(pthread_barrierattr_t *attr); + +/*@ + assigns \result, *pshared \from *attr; +*/ +extern int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, + int *restrict pshared); + +/*@ + assigns \result, *attr \from \nothing; +*/ +extern int pthread_barrierattr_init(pthread_barrierattr_t *attr); + +/*@ + assigns \result, *attr \from pshared; +*/ +extern int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared); + +/*@ + assigns \result \from thread; +*/ +extern int pthread_cancel(pthread_t thread); /*@ requires valid_cond: \valid(cond); assigns \result \from \nothing; @@ -196,10 +303,17 @@ extern int pthread_cond_destroy(pthread_cond_t * cond); extern int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr); -extern int pthread_cond_signal(pthread_cond_t *); -extern int pthread_cond_timedwait(pthread_cond_t *restrict, - pthread_mutex_t *restrict, - const struct timespec *restrict); +/*@ + assigns \result, *cond \from *cond; +*/ +extern int pthread_cond_signal(pthread_cond_t *cond); + +/*@ + assigns \result, *cond, *mutex \from *cond, *mutex, *abstime; +*/ +extern int pthread_cond_timedwait(pthread_cond_t *restrict cond, + pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime); /*@ requires valid_cond: \valid(cond); requires valid_mutex: \valid(mutex); assigns \result \from \nothing; @@ -209,16 +323,34 @@ extern int pthread_cond_timedwait(pthread_cond_t *restrict, */ extern int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex); -extern int pthread_condattr_destroy(pthread_condattr_t *); + +/*@ + assigns \result, *attr \from *attr; +*/ +extern int pthread_condattr_destroy(pthread_condattr_t *attr); + //clockid_t not available yet //extern int pthread_condattr_getclock(const pthread_condattr_t *restrict, -// clockid_t *restrict); -extern int pthread_condattr_getpshared(const pthread_condattr_t *restrict, - int *restrict); -extern int pthread_condattr_init(pthread_condattr_t *); +// clockid_t *restrict clock_id); + +/*@ + assigns \result, *pshared \from *attr; +*/ +extern int pthread_condattr_getpshared(const pthread_condattr_t *restrict attr, + int *restrict pshared); + +/*@ + assigns \result, *attr \from \nothing; +*/ +extern int pthread_condattr_init(pthread_condattr_t *attr); + //clockid_t not available yet -//extern int pthread_condattr_setclock(pthread_condattr_t *, clockid_t); -extern int pthread_condattr_setpshared(pthread_condattr_t *, int); +//extern int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id); + +/*@ + assigns \result, *attr \from pshared; +*/ +extern int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); /*@ requires valid_thread: \valid(thread); requires valid_null_attr: attr == \null || \valid_read(attr); @@ -234,15 +366,41 @@ extern int pthread_create(pthread_t *restrict thread, const pthread_attr_t *restrict attr, void *(*start_routine)(void*), void *restrict arg); -extern int pthread_detach(pthread_t); -extern int pthread_equal(pthread_t, pthread_t); -extern void pthread_exit(void *); + +/*@ + assigns \result \from thread; +*/ +extern int pthread_detach(pthread_t thread); + +/*@ + assigns \result \from indirect:t1, indirect:t2; +*/ +extern int pthread_equal(pthread_t t1, pthread_t t2); + +/*@ + assigns ((char*)value_ptr)[0..\block_length(value_ptr)-\offset(value_ptr)-1] + \from \nothing; //missing: \from 'current thread' +*/ +extern void pthread_exit(void *value_ptr); + +/*@ + assigns \result \from \nothing; //missing: \from 'current thread' +*/ extern int pthread_getconcurrency(void); + //clockid_t not available yet //extern int pthread_getcpuclockid(pthread_t, clockid_t *); -extern int pthread_getschedparam(pthread_t, int *restrict, - struct sched_param *restrict); -extern void *pthread_getspecific(pthread_key_t); + +/*@ + assigns \result, *policy, *param \from indirect:thread; //missing: \from 'thread data' +*/ +extern int pthread_getschedparam(pthread_t thread, int *restrict policy, + struct sched_param *restrict param); + +/*@ + assigns \result \from indirect:key; //missing: \from 'current thread' +*/ +extern void *pthread_getspecific(pthread_key_t key); /*@ requires valid_or_null_retval: retval == \null || \valid(retval); assigns *retval \from thread; @@ -262,9 +420,20 @@ extern void *pthread_getspecific(pthread_key_t); */ extern int pthread_join(pthread_t thread, void **retval); -extern int pthread_key_create(pthread_key_t *, void (*)(void*)); -extern int pthread_key_delete(pthread_key_t); -extern int pthread_mutex_consistent(pthread_mutex_t *); +/*@ + assigns \result, *key \from indirect:destruct; //missing: assigns 'current thread' +*/ +extern int pthread_key_create(pthread_key_t *key, void (*destruct)(void*)); + +/*@ + assigns \result \from indirect:key; //missing: assigns 'current thread' +*/ +extern int pthread_key_delete(pthread_key_t key); + +/*@ + assigns \result, *mutex \from *mutex; +*/ +extern int pthread_mutex_consistent(pthread_mutex_t *mutex); /*@ requires mutex_valid: \valid(mutex); assigns *mutex \from *mutex; @@ -273,8 +442,11 @@ extern int pthread_mutex_consistent(pthread_mutex_t *); */ extern int pthread_mutex_destroy(pthread_mutex_t *mutex); -extern int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict, - int *restrict); +/*@ + assigns \result, *mutex, *prioceiling \from *mutex; +*/ +extern int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict mutex, + int *restrict prioceiling); /*@ requires mutex_valid: \valid(mutex); requires attrs_valid_or_null: attrs == \null || \valid_read(attrs); @@ -304,11 +476,25 @@ extern int pthread_mutex_init(pthread_mutex_t *restrict mutex, // exported by our version of errno.h */ extern int pthread_mutex_lock(pthread_mutex_t * mutex); -extern int pthread_mutex_setprioceiling(pthread_mutex_t *restrict, int, - int *restrict); -extern int pthread_mutex_timedlock(pthread_mutex_t *restrict, - const struct timespec *restrict); -extern int pthread_mutex_trylock(pthread_mutex_t *); + +/*@ + assigns \result, *mutex, *old_ceiling \from *mutex, prioceiling; +*/ +extern int pthread_mutex_setprioceiling(pthread_mutex_t *restrict mutex, + int prioceiling, + int *restrict old_ceiling); + +/*@ + assigns \result, *mutex \from *mutex, *abstime; +*/ +extern int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, + const struct timespec *restrict abstime); + +/*@ + assigns \result, *mutex \from *mutex; +*/ +extern int pthread_mutex_trylock(pthread_mutex_t *mutex); + /*@ requires mutex_valid: \valid(mutex); assigns *mutex \from *mutex; @@ -322,69 +508,216 @@ extern int pthread_mutex_unlock(pthread_mutex_t *mutex); assigns *attr \from *attr; assigns \result \from indirect:*attr; ensures success_or_error: \result == 0 || \result == EINVAL; - */ +*/ extern int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); -extern int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict, - int *restrict); -extern int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict, - int *restrict); -extern int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict, - int *restrict); -extern int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict, - int *restrict); -extern int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict, - int *restrict); +/*@ + assigns \result, *prioceiling \from *attr; +*/ +extern int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *restrict attr, + int *restrict prioceiling); + +/*@ + assigns \result, *protocol \from *attr; +*/ +extern int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict attr, + int *restrict protocol); + +/*@ + assigns \result, *pshared \from *attr; +*/ +extern int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict attr, + int *restrict pshared); + +/*@ + assigns \result, *robust \from *attr; +*/ +extern int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict attr, + int *restrict robust); + +/*@ + assigns \result, *type \from *attr; +*/ +extern int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr, + int *restrict type); /*@ requires valid_attr: \valid(attr); assigns \result, *attr \from \nothing; ensures success_or_error: \result == 0 || \result == ENOMEM; - */ +*/ extern int pthread_mutexattr_init(pthread_mutexattr_t *attr); -extern int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int); -extern int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int); -extern int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); -extern int pthread_mutexattr_setrobust(pthread_mutexattr_t *, int); +/*@ + assigns \result, *attr \from *attr, prioceiling; +*/ +extern int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, + int prioceiling); + +/*@ + assigns \result, *attr \from *attr, protocol; +*/ +extern int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, + int protocol); + +/*@ + assigns \result, *attr \from *attr, pshared; +*/ +extern int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, + int pshared); + +/*@ + assigns \result, *attr \from *attr, robust; +*/ +extern int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr, + int robust); /*@ requires valid_attr: \valid(attr); assigns \result, *attr \from indirect:type; ensures success_or_error: \result == 0 || \result == EINVAL; - */ +*/ extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); -extern int pthread_once(pthread_once_t *, void (*)(void)); -extern int pthread_rwlock_destroy(pthread_rwlock_t *); -extern int pthread_rwlock_init(pthread_rwlock_t *restrict, - const pthread_rwlockattr_t *restrict); -extern int pthread_rwlock_rdlock(pthread_rwlock_t *); -extern int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict, - const struct timespec *restrict); -extern int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict, - const struct timespec *restrict); -extern int pthread_rwlock_tryrdlock(pthread_rwlock_t *); -extern int pthread_rwlock_trywrlock(pthread_rwlock_t *); -extern int pthread_rwlock_unlock(pthread_rwlock_t *); -extern int pthread_rwlock_wrlock(pthread_rwlock_t *); -extern int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); -extern int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict, - int *restrict); -extern int pthread_rwlockattr_init(pthread_rwlockattr_t *); -extern int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); +/*@ + assigns \result, *pthread_once \from *pthread_once, indirect:init_routine; +*/ +extern int pthread_once(pthread_once_t *pthread_once, + void (*init_routine)(void)); + +/*@ + assigns \result, *rwlock \from *rwlock; +*/ +extern int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); + +/*@ + assigns \result, *rwlock \from *attr; +*/ +extern int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, + const pthread_rwlockattr_t *restrict attr); + +/*@ + assigns \result, *rwlock \from *rwlock; +*/ +extern int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); + +/*@ + assigns \result, *rwlock \from *rwlock, *abstime; +*/ +extern int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rwlock, + const struct timespec *restrict abstime); + +/*@ + assigns \result, *rwlock \from *rwlock, *abstime; +*/ +extern int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rwlock, + const struct timespec *restrict abstime); + +/*@ + assigns \result, *rwlock \from *rwlock; +*/ +extern int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); + +/*@ + assigns \result, *rwlock \from *rwlock; +*/ +extern int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); + +/*@ + assigns \result, *rwlock \from *rwlock; +*/ +extern int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); + +/*@ + assigns \result, *rwlock \from *rwlock; +*/ +extern int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); + +/*@ + assigns \result, *attr \from *attr; +*/ +extern int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); + +/*@ + assigns \result, *pshared \from *attr; +*/ +extern int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict attr, + int *restrict pshared); + +/*@ + assigns \result, *attr \from \nothing; +*/ +extern int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); + +/*@ + assigns \result, *attr \from *attr, pshared; +*/ +extern int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared); + +/*@ + assigns \result \from \nothing; //missing: \from 'current thread' +*/ extern pthread_t pthread_self(void); -extern int pthread_setcancelstate(int, int *); -extern int pthread_setcanceltype(int, int *); -extern int pthread_setconcurrency(int); -extern int pthread_setschedparam(pthread_t, int, const struct sched_param *); -extern int pthread_setschedprio(pthread_t, int); -extern int pthread_setspecific(pthread_key_t, const void *); -extern int pthread_spin_destroy(pthread_spinlock_t *); -extern int pthread_spin_init(pthread_spinlock_t *, int); -extern int pthread_spin_lock(pthread_spinlock_t *); -extern int pthread_spin_trylock(pthread_spinlock_t *); -extern int pthread_spin_unlock(pthread_spinlock_t *); + +/*@ + assigns \result, *oldstate \from state; //missing: \from 'current thread' +*/ +extern int pthread_setcancelstate(int state, int *oldstate); + +/*@ + assigns \result, *oldtype \from type; //missing: \from 'current thread' +*/ +extern int pthread_setcanceltype(int type, int *oldtype); + +/*@ + assigns \result \from indirect:new_level; //missing: assigns 'current thread' +*/ +extern int pthread_setconcurrency(int new_level); + +/*@ + assigns \result \from indirect:thread, indirect:policy, indirect:*param; //missing: assigns 'current thread' +*/ +extern int pthread_setschedparam(pthread_t thread, int policy, + const struct sched_param *param); + +/*@ + assigns \result \from indirect:thread, indirect:prio; //missing: assigns 'current thread' +*/ +extern int pthread_setschedprio(pthread_t thread, int prio); + +/*@ + assigns \result \from indirect:key, indirect:value; //missing: assigns 'current thread data' +*/ +extern int pthread_setspecific(pthread_key_t key, const void *value); + +/*@ + assigns \result, *lock \from *lock; +*/ +extern int pthread_spin_destroy(pthread_spinlock_t *lock); + +/*@ + assigns \result, *lock \from pshared; +*/ +extern int pthread_spin_init(pthread_spinlock_t *lock, int pshared); + +/*@ + assigns \result, *lock \from *lock; +*/ +extern int pthread_spin_lock(pthread_spinlock_t *lock); + +/*@ + assigns \result, *lock \from *lock; +*/ +extern int pthread_spin_trylock(pthread_spinlock_t *lock); + +/*@ + assigns \result, *lock \from *lock; +*/ +extern int pthread_spin_unlock(pthread_spinlock_t *lock); + +/*@ + assigns \nothing; //missing: assigns 'current thread' +*/ extern void pthread_testcancel(void); // GNU extensions diff --git a/share/libc/pwd.h b/share/libc/pwd.h index 101e35e3df1..e3dcb358014 100644 --- a/share/libc/pwd.h +++ b/share/libc/pwd.h @@ -113,8 +113,23 @@ extern int getpwnam_r(const char *name, struct passwd *pwd, extern int getpwuid_r(uid_t uid, struct passwd *pwd, char *buf, size_t buflen, struct passwd **result); +// Represents the user database and its current entry +struct passwd __fc_pwent; + +/*@ + assigns __fc_pwent \from __fc_pwent; +*/ extern void endpwent(void); + +/*@ + assigns __fc_pwent \from __fc_pwent; + assigns \result \from &__fc_pwent; +*/ extern struct passwd *getpwent(void); + +/*@ + assigns __fc_pwent \from __fc_pwent; +*/ extern void setpwent(void); __END_DECLS diff --git a/share/libc/semaphore.h b/share/libc/semaphore.h index bae1236fcf3..5ad03082ad2 100644 --- a/share/libc/semaphore.h +++ b/share/libc/semaphore.h @@ -36,16 +36,58 @@ typedef union __fc_sem_t { #define SEM_FAILED ((sem_t *) 0) -extern int sem_close(sem_t *); -extern int sem_destroy(sem_t *); -extern int sem_getvalue(sem_t *restrict, int *restrict); -extern int sem_init(sem_t *, int, unsigned); -extern sem_t *sem_open(const char *, int, ...); -extern int sem_post(sem_t *); -extern int sem_timedwait(sem_t *restrict, const struct timespec *restrict); -extern int sem_trywait(sem_t *); -extern int sem_unlink(const char *); -extern int sem_wait(sem_t *); +/*@ + frees sem; + assigns \result \from *sem; +*/ +extern int sem_close(sem_t *sem); + +/*@ + assigns \result, *sem \from *sem; +*/ +extern int sem_destroy(sem_t *sem); + +/*@ + assigns \result, *sval \from *sem; +*/ +extern int sem_getvalue(sem_t *restrict sem, int *restrict sval); + +/*@ + assigns \result, *sem \from *sem, pshared, value; +*/ +extern int sem_init(sem_t *sem, int pshared, unsigned value); + +/*@ + allocates \result; + assigns \result \from indirect:name[0..], oflag; //missing: \from variadic args +*/ +extern sem_t *sem_open(const char *name, int oflag, ...); + +/*@ + assigns \result, *sem \from *sem; +*/ +extern int sem_post(sem_t *sem); + +/*@ + assigns \result, *sem \from *sem, *abstime; +*/ +extern int sem_timedwait(sem_t *restrict sem, + const struct timespec *restrict abstime); + +/*@ + assigns \result, *sem \from *sem; +*/ +extern int sem_trywait(sem_t *sem); + +/*@ + assigns \result \from indirect:name[0..]; //missing: assigns 'named semaphore' +*/ +extern int sem_unlink(const char *name); + +/*@ + assigns \result, *sem \from *sem; +*/ +extern int sem_wait(sem_t *sem); __END_DECLS __POP_FC_STDLIB diff --git a/share/libc/signal.h b/share/libc/signal.h index 94848b2e723..082f1e39dae 100644 --- a/share/libc/signal.h +++ b/share/libc/signal.h @@ -47,8 +47,13 @@ typedef void (*__fc_sighandler_t) (int); /* for BSD 4.4 */ typedef __fc_sighandler_t sig_t; +/*@ assigns \nothing; */ extern void __fc_sig_dfl(int); + +/*@ assigns \nothing; */ extern void __fc_sig_ign(int); + +/*@ assigns \nothing; */ extern void __fc_sig_err(int); #define SIG_DFL (&__fc_sig_dfl) /* default signal handling */ diff --git a/share/libc/spawn.h b/share/libc/spawn.h index 6dae29babee..51b21aa891d 100644 --- a/share/libc/spawn.h +++ b/share/libc/spawn.h @@ -46,73 +46,147 @@ typedef struct __fc_posix_posix_spawn_file_actions_t { #define POSIX_SPAWN_SETSIGDEF 0x04 #define POSIX_SPAWN_SETSIGMASK 0x08 +/*@ + assigns *pid, \result \from + indirect:path[0..], + indirect:*file_actions, + indirect:*attrp, + indirect:*argv[0..], + indirect:*envp[0..]; +*/ extern int posix_spawn(pid_t *restrict pid, const char *restrict path, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *restrict attrp, char *const *restrict argv, char *const *restrict envp); +/*@ + assigns \result, *file_actions \from fildes; +*/ extern int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions, int fildes); +/*@ + assigns \result, *file_actions \from fildes, newfildes; +*/ extern int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions, int fildes, int newfildes); +/*@ + assigns \result, *file_actions + \from fildes, path[0..], oflag, mode; +*/ extern int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *restrict file_actions, int fildes, const char *restrict path, int oflag, mode_t mode); +/*@ + assigns \result, *file_actions \from \nothing; // missing: \from 'filesystem' +*/ extern int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions); +/*@ + assigns \result, *file_actions \from \nothing; // missing: \from 'filesystem' +*/ extern int posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions); +/*@ + assigns \result, *attr \from \nothing; +*/ extern int posix_spawnattr_destroy(posix_spawnattr_t *attr); +/*@ + assigns \result, *flags \from *attr; +*/ extern int posix_spawnattr_getflags(const posix_spawnattr_t *restrict attr, short *restrict flags); +/*@ + assigns \result, *pgroup \from *attr; +*/ extern int posix_spawnattr_getpgroup(const posix_spawnattr_t *restrict attr, pid_t *restrict pgroup); +/*@ + assigns \result, *schedparam \from *attr; +*/ extern int posix_spawnattr_getschedparam(const posix_spawnattr_t *restrict attr, struct sched_param *restrict schedparam); +/*@ + assigns \result, *schedpolicy \from *attr; +*/ extern int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *restrict attr, int *restrict schedpolicy); +/*@ + assigns \result, *sigdefault \from *attr; +*/ extern int posix_spawnattr_getsigdefault(const posix_spawnattr_t *restrict attr, sigset_t *restrict sigdefault); +/*@ + assigns \result, *sigmask \from *attr; +*/ extern int posix_spawnattr_getsigmask(const posix_spawnattr_t *restrict attr, - sigset_t *restrict); + sigset_t *restrict sigmask); +/*@ + assigns \result, *attr \from \nothing; +*/ extern int posix_spawnattr_init(posix_spawnattr_t *attr); +/*@ + assigns \result, *attr \from flags; +*/ extern int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags); +/*@ + assigns \result, *attr \from pgroup; +*/ extern int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgroup); +/*@ + assigns \result, *attr \from *schedparam; +*/ extern int posix_spawnattr_setschedparam(posix_spawnattr_t *restrict attr, const struct sched_param *restrict schedparam); +/*@ + assigns \result, *attr \from schedpolicy; +*/ extern int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int schedpolicy); +/*@ + assigns \result, *attr \from *sigdefault; +*/ extern int posix_spawnattr_setsigdefault(posix_spawnattr_t *restrict attr, const sigset_t *restrict sigdefault); +/*@ + assigns \result, *attr \from *sigmask; +*/ extern int posix_spawnattr_setsigmask(posix_spawnattr_t *restrict attr, const sigset_t *restrict sigmask); +/*@ + assigns *pid, \result \from + indirect:file[0..], //missing: '\from PWD' + indirect:*file_actions, + indirect:*attrp, + indirect:*argv[0..], + indirect:*envp[0..]; +*/ extern int posix_spawnp(pid_t *restrict pid, const char *restrict file, const posix_spawn_file_actions_t *file_actions, const posix_spawnattr_t *restrict attrp, diff --git a/share/libc/strings.h b/share/libc/strings.h index 0bc801348bb..ee25b389858 100644 --- a/share/libc/strings.h +++ b/share/libc/strings.h @@ -29,32 +29,52 @@ __PUSH_FC_STDLIB __BEGIN_DECLS -extern int bcmp(const void *, const void *, size_t); -extern void bcopy(const void *, void *, size_t); +/*@ + assigns \result \from indirect:((char*)s1)[0 .. n-1], + indirect:((char*)s2)[0 .. n-1]; +*/ +extern int bcmp(const void *s1, const void *s2, size_t n); + +/*@ + assigns ((char*)dest)[0 .. n-1] \from ((char*)src)[0 .. n-1], indirect:n; +*/ +extern void bcopy(const void *src, void *dest, size_t n); /*@ requires valid_memory_area: \valid (((char*) s)+(0 .. n-1)); assigns ((char*) s)[0 .. n-1] \from \nothing; ensures s_initialized:initialization:\initialized(((char*) s)+(0 .. n-1)); ensures zero_initialized: \subset(((char*) s)[0 .. n-1], {0}); */ -extern void bzero(void *s, size_t n); -extern int ffs(int); -extern char *index(const char *, int); -extern char *rindex(const char *, int); +extern void bzero(void *s, size_t n); + +/*@ + assigns \result \from i; +*/ +extern int ffs(int i); + +/*@ + assigns \result \from s, indirect:s[0 .. strlen(s)], indirect:c; +*/ +extern char *index(const char *s, int c); + +/*@ + assigns \result \from s, indirect:s[0 .. strlen(s)], indirect:c; +*/ +extern char *rindex(const char *s, int c); /*@ requires valid_string_s1: valid_read_string(s1); requires valid_string_s2: valid_read_string(s2); assigns \result \from indirect:s1[0..], indirect:s2[0..]; */ -extern int strcasecmp(const char *s1, const char *s2); +extern int strcasecmp(const char *s1, const char *s2); /*@ requires valid_string_s1: valid_read_nstring(s1, n); requires valid_string_s2: valid_read_nstring(s2, n); assigns \result \from indirect:n, indirect:s1[0..n-1], indirect:s2[0..n-1]; */ -extern int strncasecmp(const char *s1, const char *s2, size_t n); +extern int strncasecmp(const char *s1, const char *s2, size_t n); __END_DECLS diff --git a/share/libc/utmp.h b/share/libc/utmp.h index 388073413a2..3f7894f0e62 100644 --- a/share/libc/utmp.h +++ b/share/libc/utmp.h @@ -28,22 +28,12 @@ __PUSH_FC_STDLIB #include "__fc_define_pid_t.h" +#include "__fc_utmp_constants.h" #include "sys/time.h" #include "stdint.h" __BEGIN_DECLS -#define _PATH_UTMP "/var/run/utmp" -#define UTMP_FILE _PATH_UTMP -#define UTMP_FILENAME _PATH_UTMP -#define _PATH_WTMP "/var/log/wtmp" -#define WTMP_FILE _PATH_WTMP -#define WTMP_FILENAME _PATH_WTMP - -#define UT_LINESIZE 32 -#define UT_NAMESIZE 32 -#define UT_HOSTSIZE 256 - struct lastlog { time_t ll_time; @@ -72,36 +62,96 @@ struct utmp char __glibc_reserved[20]; // used by who.c }; -#define ut_name ut_user -#define ut_time ut_tv.tv_sec - +/*@ + assigns \result, __fc_fopen[fd] \from __fc_fopen[fd], fd; +*/ extern int login_tty (int fd); -extern void login (const struct utmp *entry); + +// static storage used by some getter functions +extern struct utmp __fc_get; + +/*@ + assigns __fc_utmp \from __fc_utmp, *ut; + assigns __fc_wtmp \from __fc_wtmp, *ut; +*/ +extern void login (const struct utmp *ut); + +/*@ + assigns __fc_utmp \from __fc_wtmp, *ut_line; + assigns \result \from indirect:__fc_wtmp, indirect:*ut_line; +*/ extern int logout (const char *ut_line); + +/*@ + assigns __fc_wtmp \from __fc_wtmp, ut_line[0..], ut_name[0..], ut_host[0..]; +*/ extern void logwtmp (const char *ut_line, const char *ut_name, const char *ut_host); +/*@ + assigns \nothing; // missing: assigns 'file named wtmp_file in the filesystem' \from *utmp; +*/ extern void updwtmp (const char *wtmp_file, const struct utmp *utmp); +/*@ + assigns \result \from file[0..]; // missing: assigns 'file named file in the filesystem'; +*/ extern int utmpname (const char *file); +/*@ + assigns \result \from &__fc_get, indirect:__fc_utmp; + assigns __fc_get \from __fc_get, indirect:__fc_utmp; +*/ extern struct utmp *getutent (void); +/*@ + assigns __fc_utmp \from __fc_utmp; +*/ extern void setutent (void); +/*@ + assigns __fc_utmp \from __fc_utmp; +*/ extern void endutent (void); +/*@ + assigns \result \from &__fc_get, indirect:__fc_utmp, indirect:*id; + assigns __fc_get \from __fc_get, indirect:__fc_utmp, indirect:*id; +*/ extern struct utmp *getutid (const struct utmp *id); +/*@ + assigns \result \from &__fc_get, indirect:__fc_utmp, indirect:*line; + assigns __fc_get \from __fc_get, indirect:__fc_utmp, indirect:*line; +*/ extern struct utmp *getutline (const struct utmp *line); +/*@ + assigns __fc_utmp \from __fc_utmp, *utmp_ptr; + assigns \result \from utmp_ptr; +*/ extern struct utmp *pututline (const struct utmp *utmp_ptr); +/*@ + assigns \result \from indirect:__fc_utmp; + assigns *buffer \from __fc_utmp; + assigns *result \from &__fc_utmp; +*/ extern int getutent_r (struct utmp *buffer, struct utmp **result); +/*@ + assigns \result \from indirect:*id, indirect:__fc_utmp; + assigns *buffer \from indirect:*id, __fc_utmp; + assigns *result \from indirect:*id, &__fc_utmp; +*/ extern int getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result); +/*@ + assigns \result \from indirect:*line, indirect:__fc_utmp; + assigns *buffer \from indirect:*line, __fc_utmp; + assigns *result \from indirect:*line, &__fc_utmp; +*/ extern int getutline_r (const struct utmp *line, struct utmp *buffer, struct utmp **result); diff --git a/share/libc/utmpx.h b/share/libc/utmpx.h index 876076f94c2..0fd2bc7817b 100644 --- a/share/libc/utmpx.h +++ b/share/libc/utmpx.h @@ -26,6 +26,7 @@ __PUSH_FC_STDLIB #include "__fc_define_pid_t.h" +#include "__fc_utmp_constants.h" #include "stdint.h" #include "sys/time.h" @@ -46,21 +47,42 @@ struct utmpx { char __glibc_reserved[20]; // not POSIX, but allowed by it }; -#define EMPTY 0 -#define BOOT_TIME 2 -#define OLD_TIME 4 -#define NEW_TIME 3 -#define USER_PROCESS 7 -#define INIT_PROCESS 5 -#define LOGIN_PROCESS 6 -#define DEAD_PROCESS 8 +// static storage used by some getter functions +extern struct utmpx __fc_getx; -extern void endutxent(void); -extern struct utmpx *getutxent(void); -extern struct utmpx *getutxid(const struct utmpx *); -extern struct utmpx *getutxline(const struct utmpx *); -extern struct utmpx *pututxline(const struct utmpx *); -extern void setutxent(void); +/*@ + assigns \result \from &__fc_getx, indirect:__fc_utmp; + assigns __fc_getx \from __fc_getx, indirect:__fc_utmp; +*/ +extern struct utmpx *getutxent (void); + +/*@ + assigns __fc_utmp \from __fc_utmp; +*/ +extern void setutxent (void); + +/*@ + assigns __fc_utmp \from __fc_utmp; +*/ +extern void endutxent (void); + +/*@ + assigns \result \from &__fc_getx, indirect:__fc_utmp, indirect:*id; + assigns __fc_getx \from __fc_getx, indirect:__fc_utmp, indirect:*id; +*/ +extern struct utmpx *getutxid (const struct utmpx *id); + +/*@ + assigns \result \from &__fc_getx, indirect:__fc_utmp, indirect:*line; + assigns __fc_getx \from __fc_getx, indirect:__fc_utmp, indirect:*line; +*/ +extern struct utmpx *getutxline (const struct utmpx *line); + +/*@ + assigns __fc_utmp \from __fc_utmp, *utmp_ptr; + assigns \result \from utmp_ptr; +*/ +extern struct utmpx *pututxline (const struct utmpx *utmp_ptr); __END_DECLS __POP_FC_STDLIB diff --git a/tests/libc/fc_libc.c b/tests/libc/fc_libc.c index 4d4ec0cf07d..30692f59a93 100644 --- a/tests/libc/fc_libc.c +++ b/tests/libc/fc_libc.c @@ -97,6 +97,7 @@ #include "fcntl.h" #include "__fc_select.h" #include "__fc_string_axiomatic.h" +#include "__fc_utmp_constants.h" #include "features.h" #include "fenv.h" #include "float.h" -- GitLab