attributes(7) — Linux manual page

NAME | DESCRIPTION | SEE ALSO | COLOPHON

attributes(7)        Miscellaneous Information Manual       attributes(7)

NAME         top

       attributes - POSIX safety concepts

DESCRIPTION         top

       Note: the text of this man page is based on the material taken
       from the "POSIX Safety Concepts" section of the GNU C Library
       manual.  Further details on the topics described here can be found
       in that manual.

       Various function manual pages include a section ATTRIBUTES that
       describes the safety of calling the function in various contexts.
       This section annotates functions with the following safety
       markings:

       MT-Safe
              MT-Safe or Thread-Safe functions are safe to call in the
              presence of other threads.  MT, in MT-Safe, stands for
              Multi Thread.

              Being MT-Safe does not imply a function is atomic, nor that
              it uses any of the memory synchronization mechanisms POSIX
              exposes to users.  It is even possible that calling MT-Safe
              functions in sequence does not yield an MT-Safe
              combination.  For example, having a thread call two MT-Safe
              functions one right after the other does not guarantee
              behavior equivalent to atomic execution of a combination of
              both functions, since concurrent calls in other threads may
              interfere in a destructive way.

              Whole-program optimizations that could inline functions
              across library interfaces may expose unsafe reordering, and
              so performing inlining across the GNU C Library interface
              is not recommended.  The documented MT-Safety status is not
              guaranteed under whole-program optimization.  However,
              functions defined in user-visible headers are designed to
              be safe for inlining.

       MT-Unsafe
              MT-Unsafe functions are not safe to call in a multithreaded
              programs.

       Other keywords that appear in safety notes are defined in
       subsequent sections.

   Conditionally safe features
       For some features that make functions unsafe to call in certain
       contexts, there are known ways to avoid the safety problem other
       than refraining from calling the function altogether.  The
       keywords that follow refer to such features, and each of their
       definitions indicates how the whole program needs to be
       constrained in order to remove the safety problem indicated by the
       keyword.  Only when all the reasons that make a function unsafe
       are observed and addressed, by applying the documented
       constraints, does the function become safe to call in a context.

       init   Functions marked with init as an MT-Unsafe feature perform
              MT-Unsafe initialization when they are first called.

              Calling such a function at least once in single-threaded
              mode removes this specific cause for the function to be
              regarded as MT-Unsafe.  If no other cause for that remains,
              the function can then be safely called after other threads
              are started.

       race   Functions annotated with race as an MT-Safety issue operate
              on objects in ways that may cause data races or similar
              forms of destructive interference out of concurrent
              execution.  In some cases, the objects are passed to the
              functions by users; in others, they are used by the
              functions to return values to users; in others, they are
              not even exposed to users.

       const  Functions marked with const as an MT-Safety issue non-
              atomically modify internal objects that are better regarded
              as constant, because a substantial portion of the GNU C
              Library accesses them without synchronization.  Unlike
              race, which causes both readers and writers of internal
              objects to be regarded as MT-Unsafe, this mark is applied
              to writers only.  Writers remain MT-Unsafe to call, but the
              then-mandatory constness of objects they modify enables
              readers to be regarded as MT-Safe (as long as no other
              reasons for them to be unsafe remain), since the lack of
              synchronization is not a problem when the objects are
              effectively constant.

              The identifier that follows the const mark will appear by
              itself as a safety note in readers.  Programs that wish to
              work around this safety issue, so as to call writers, may
              use a non-recursive read-write lock associated with the
              identifier, and guard all calls to functions marked with
              const followed by the identifier with a write lock, and all
              calls to functions marked with the identifier by itself
              with a read lock.

       sig    Functions marked with sig as a MT-Safety issue may
              temporarily install a signal handler for internal purposes,
              which may interfere with other uses of the signal,
              identified after a colon.

              This safety problem can be worked around by ensuring that
              no other uses of the signal will take place for the
              duration of the call.  Holding a non-recursive mutex while
              calling all functions that use the same temporary signal;
              blocking that signal before the call and resetting its
              handler afterwards is recommended.

       term   Functions marked with term as an MT-Safety issue may change
              the terminal settings in the recommended way, namely: call
              tcgetattr(3), modify some flags, and then call
              tcsetattr(3), this creates a window in which changes made
              by other threads are lost.  Thus, functions marked with
              term are MT-Unsafe.

              It is thus advisable for applications using the terminal to
              avoid concurrent and reentrant interactions with it, by not
              using it in signal handlers or blocking signals that might
              use it, and holding a lock while calling these functions
              and interacting with the terminal.  This lock should also
              be used for mutual exclusion with functions marked with
              race:tcattr(fd), where fd is a file descriptor for the
              controlling terminal.  The caller may use a single mutex
              for simplicity, or use one mutex per terminal, even if
              referenced by different file descriptors.

   Other safety remarks
       Additional keywords may be attached to functions, indicating
       features that do not make a function unsafe to call, but that may
       need to be taken into account in certain classes of programs:

       locale Functions annotated with locale as an MT-Safety issue read
              from the locale object without any form of synchronization.
              Functions annotated with locale called concurrently with
              locale changes may behave in ways that do not correspond to
              any of the locales active during their execution, but an
              unpredictable mix thereof.

              We do not mark these functions as MT-Unsafe, however,
              because functions that modify the locale object are marked
              with const:locale and regarded as unsafe.  Being unsafe,
              the latter are not to be called when multiple threads are
              running or asynchronous signals are enabled, and so the
              locale can be considered effectively constant in these
              contexts, which makes the former safe.

       env    Functions marked with env as an MT-Safety issue access the
              environment with getenv(3) or similar, without any guards
              to ensure safety in the presence of concurrent
              modifications.

              We do not mark these functions as MT-Unsafe, however,
              because functions that modify the environment are all
              marked with const:env and regarded as unsafe.  Being
              unsafe, the latter are not to be called when multiple
              threads are running or asynchronous signals are enabled,
              and so the environment can be considered effectively
              constant in these contexts, which makes the former safe.

       hostid Functions marked with hostid as an MT-Safety issue read
              from the system-wide data structures that hold the "host
              ID" of the machine.  These data structures cannot generally
              be modified atomically.  Since it is expected that the
              "host ID" will not normally change, the function that reads
              from it (gethostid(3)) is regarded as safe, whereas the
              function that modifies it (sethostid(3)) is marked with
              const:hostid, indicating it may require special care if it
              is to be called.  In this specific case, the special care
              amounts to system-wide (not merely intra-process)
              coordination.

       sigintr
              Functions marked with sigintr as an MT-Safety issue access
              the GNU C Library _sigintr internal data structure without
              any guards to ensure safety in the presence of concurrent
              modifications.

              We do not mark these functions as MT-Unsafe, however,
              because functions that modify this data structure are all
              marked with const:sigintr and regarded as unsafe.  Being
              unsafe, the latter are not to be called when multiple
              threads are running or asynchronous signals are enabled,
              and so the data structure can be considered effectively
              constant in these contexts, which makes the former safe.

       cwd    Functions marked with cwd as an MT-Safety issue may
              temporarily change the current working directory during
              their execution, which may cause relative pathnames to be
              resolved in unexpected ways in other threads or within
              asynchronous signal or cancelation handlers.

              This is not enough of a reason to mark so-marked functions
              as MT-Unsafe, but when this behavior is optional (e.g.,
              nftw(3) with FTW_CHDIR), avoiding the option may be a good
              alternative to using full pathnames or file descriptor-
              relative (e.g., openat(2)) system calls.

       :identifier
              Annotations may sometimes be followed by identifiers,
              intended to group several functions that, for example,
              access the data structures in an unsafe way, as in race and
              const, or to provide more specific information, such as
              naming a signal in a function marked with sig.  It is
              envisioned that it may be applied to lock and corrupt as
              well in the future.

              In most cases, the identifier will name a set of functions,
              but it may name global objects or function arguments, or
              identifiable properties or logical components associated
              with them, with a notation such as, for example, :buf(arg)
              to denote a buffer associated with the argument arg, or
              :tcattr(fd) to denote the terminal attributes of a file
              descriptor fd.

              The most common use for identifiers is to provide logical
              groups of functions and arguments that need to be protected
              by the same synchronization primitive in order to ensure
              safe operation in a given context.

       /condition
              Some safety annotations may be conditional, in that they
              only apply if a boolean expression involving arguments,
              global variables or even the underlying kernel evaluates to
              true.  For example, /!ps and /one_per_line indicate the
              preceding marker only applies when argument ps is NULL, or
              global variable one_per_line is nonzero.

              When all marks that render a function unsafe are adorned
              with such conditions, and none of the named conditions
              hold, then the function can be regarded as safe.

SEE ALSO         top

       pthreads(7), signal-safety(7)

COLOPHON         top

       This page is part of the man-pages (Linux kernel and C library
       user-space interface documentation) project.  Information about
       the project can be found at 
       ⟨https://www.kernel.org/doc/man-pages/⟩.  If you have a bug report
       for this manual page, see
       ⟨https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/CONTRIBUTING⟩.
       This page was obtained from the tarball man-pages-6.10.tar.gz
       fetched from
       ⟨https://mirrors.edge.kernel.org/pub/linux/docs/man-pages/⟩ on
       2025-02-02.  If you discover any rendering problems in this HTML
       version of the page, or you believe there is a better or more up-
       to-date source for the page, or you have corrections or
       improvements to the information in this COLOPHON (which is not
       part of the original manual page), send a mail to
       man-pages@man7.org

Linux man-pages 6.10            2024-11-17                  attributes(7)

Pages that refer to this page: adjtimex(2)clock_getres(2)eventfd(2)getrlimit(2)getrusage(2)mmap(2)sigaltstack(2)utimensat(2)a64l(3)abort(3)abs(3)acos(3)acosh(3)addseverity(3)adjtime(3)aio_cancel(3)aio_error(3)aio_fsync(3)aio_read(3)aio_return(3)aio_suspend(3)aio_write(3)alloca(3)arc4random(3)argz_add(3)asin(3)asinh(3)asprintf(3)assert(3)assert_perror(3)atan2(3)atan(3)atanh(3)atexit(3)atof(3)atoi(3)backtrace(3)basename(3)bcopy(3)bindresvport(3)bsd_signal(3)bsearch(3)btowc(3)byteorder(3)bzero(3)cabs(3)cacos(3)cacosh(3)canonicalize_file_name(3)carg(3)casin(3)casinh(3)catan(3)catanh(3)catgets(3)catopen(3)cbrt(3)ccos(3)ceil(3)cexp(3)cfree(3)cimag(3)clearenv(3)clock(3)clock_getcpuclockid(3)clog10(3)clog(3)closedir(3)confstr(3)conj(3)copysign(3)cos(3)cosh(3)cpow(3)cproj(3)creal(3)crypt(3)csin(3)csinh(3)csqrt(3)ctan(3)ctanh(3)ctermid(3)ctime(3)daemon(3)des_crypt(3)difftime(3)dirfd(3)div(3)dladdr(3)dlerror(3)dlinfo(3)dl_iterate_phdr(3)dlopen(3)dlsym(3)drand48(3)drand48_r(3)dysize(3)ecvt(3)ecvt_r(3)encrypt(3)envz_add(3)erf(3)erfc(3)err(3)error(3)ether_aton(3)euidaccess(3)exec(3)exit(3)exp10(3)exp2(3)exp(3)expm1(3)fabs(3)fclose(3)fcloseall(3)fdim(3)fenv(3)ferror(3)fexecve(3)fflush(3)ffs(3)fgetc(3)fgetgrent(3)fgetpwent(3)fgetwc(3)fgetws(3)fileno(3)finite(3)flockfile(3)floor(3)fma(3)fmax(3)fmemopen(3)fmin(3)fmod(3)fmtmsg(3)fnmatch(3)fopen(3)fopencookie(3)fpathconf(3)fpclassify(3)fpurge(3)fputwc(3)fputws(3)fread(3)frexp(3)fseek(3)fseeko(3)ftime(3)ftok(3)fts(3)ftw(3)futimes(3)gamma(3)gcvt(3)getaddrinfo(3)getaddrinfo_a(3)getauxval(3)getcontext(3)getcwd(3)getdate(3)getdirentries(3)getdtablesize(3)getenv(3)getfsent(3)getgrent(3)getgrent_r(3)getgrnam(3)getgrouplist(3)gethostbyname(3)gethostid(3)getifaddrs(3)getline(3)getloadavg(3)getlogin(3)getmntent(3)getnameinfo(3)getnetent(3)getnetent_r(3)get_nprocs(3)getopt(3)getpass(3)getprotoent(3)getprotoent_r(3)getpt(3)getpw(3)getpwent(3)getpwent_r(3)getpwnam(3)getrpcent(3)getrpcent_r(3)getrpcport(3)gets(3)getservent(3)getservent_r(3)getspnam(3)getsubopt(3)getttyent(3)getusershell(3)getutent(3)getutmp(3)getw(3)getwchar(3)glob(3)gnu_get_libc_version(3)grantpt(3)gsignal(3)hsearch(3)hypot(3)iconv(3)iconv_close(3)iconv_open(3)if_nameindex(3)if_nametoindex(3)ilogb(3)inet(3)inet_ntop(3)inet_pton(3)initgroups(3)insque(3)isalpha(3)isatty(3)isgreater(3)iswalnum(3)iswalpha(3)iswblank(3)iswcntrl(3)iswctype(3)iswdigit(3)iswgraph(3)iswlower(3)iswprint(3)iswpunct(3)iswspace(3)iswupper(3)iswxdigit(3)j0(3)key_setsecret(3)ldexp(3)lio_listio(3)localeconv(3)lockf(3)log10(3)log1p(3)log2(3)log(3)logb(3)login(3)lrint(3)lround(3)lsearch(3)lseek64(3)makecontext(3)makedev(3)mallinfo(3)malloc(3)malloc_get_state(3)malloc_info(3)malloc_stats(3)malloc_trim(3)malloc_usable_size(3)matherr(3)mblen(3)mbrlen(3)mbrtowc(3)mbsinit(3)mbsnrtowcs(3)mbsrtowcs(3)mbstowcs(3)mbtowc(3)mcheck(3)memccpy(3)memchr(3)memcmp(3)memcpy(3)memfrob(3)memmem(3)memmove(3)mempcpy(3)memset(3)mkdtemp(3)mkfifo(3)mkstemp(3)mktemp(3)modf(3)mq_close(3)mq_getattr(3)mq_notify(3)mq_open(3)mq_receive(3)mq_send(3)mq_unlink(3)mtrace(3)nan(3)nextafter(3)nextup(3)nl_langinfo(3)ntp_gettime(3)on_exit(3)opendir(3)open_memstream(3)openpty(3)perror(3)popen(3)posix_fallocate(3)posix_memalign(3)posix_openpt(3)pow10(3)pow(3)__ppc_set_ppr_med(3)__ppc_yield(3)printf(3)profil(3)psignal(3)pthread_attr_init(3)pthread_attr_setaffinity_np(3)pthread_attr_setdetachstate(3)pthread_attr_setguardsize(3)pthread_attr_setinheritsched(3)pthread_attr_setschedparam(3)pthread_attr_setschedpolicy(3)pthread_attr_setscope(3)pthread_attr_setsigmask_np(3)pthread_attr_setstack(3)pthread_attr_setstackaddr(3)pthread_attr_setstacksize(3)pthread_cancel(3)pthread_cleanup_push(3)pthread_create(3)pthread_detach(3)pthread_equal(3)pthread_exit(3)pthread_getattr_default_np(3)pthread_getattr_np(3)pthread_getcpuclockid(3)pthread_join(3)pthread_kill(3)pthread_kill_other_threads_np(3)pthread_self(3)pthread_setaffinity_np(3)pthread_setcancelstate(3)pthread_setconcurrency(3)pthread_setname_np(3)pthread_setschedparam(3)pthread_setschedprio(3)pthread_sigmask(3)pthread_sigqueue(3)pthread_testcancel(3)pthread_tryjoin_np(3)pthread_yield(3)ptsname(3)putenv(3)putgrent(3)putpwent(3)puts(3)putwchar(3)qecvt(3)qsort(3)raise(3)rand(3)random(3)random_r(3)rcmd(3)readdir(3)readdir_r(3)realpath(3)re_comp(3)regex(3)remainder(3)remove(3)remquo(3)resolver(3)rewinddir(3)rexec(3)rint(3)round(3)rpc(3)rpmatch(3)rtime(3)scalb(3)scalbln(3)scandir(3)scanf(3)sched_getcpu(3)seekdir(3)sem_close(3)sem_destroy(3)sem_getvalue(3)sem_init(3)sem_open(3)sem_post(3)sem_unlink(3)sem_wait(3)setaliasent(3)setbuf(3)setenv(3)setjmp(3)setlocale(3)setlogmask(3)setnetgrent(3)shm_open(3)siginterrupt(3)signbit(3)significand(3)sigpause(3)sigqueue(3)sigset(3)sigsetops(3)sigvec(3)sigwait(3)sin(3)sincos(3)sinh(3)sleep(3)sockatmark(3)sqrt(3)sscanf(3)statvfs(3)stdarg(3)stdio_ext(3)stpncpy(3)strcasecmp(3)strchr(3)strcmp(3)strcoll(3)strcpy(3)strdup(3)strerror(3)strfmon(3)strfromd(3)strfry(3)strftime(3)strlen(3)strncat(3)strnlen(3)strpbrk(3)strptime(3)strsep(3)strsignal(3)strspn(3)strstr(3)strtod(3)strtoimax(3)strtok(3)strtol(3)strtoul(3)strverscmp(3)strxfrm(3)swab(3)sysconf(3)syslog(3)system(3)sysv_signal(3)tan(3)tanh(3)tcgetpgrp(3)tcgetsid(3)telldir(3)tempnam(3)termios(3)tgamma(3)timegm(3)timespec_get(3)tmpfile(3)tmpnam(3)toascii(3)toupper(3)towctrans(3)towlower(3)towupper(3)trunc(3)tsearch(3)ttyname(3)ttyslot(3)tzset(3)ualarm(3)ulimit(3)ungetwc(3)unlocked_stdio(3)unlockpt(3)updwtmp(3)usleep(3)wcpcpy(3)wcpncpy(3)wcrtomb(3)wcscasecmp(3)wcscat(3)wcschr(3)wcscmp(3)wcscpy(3)wcscspn(3)wcsdup(3)wcslen(3)wcsncat(3)wcsncmp(3)wcsncpy(3)wcsnlen(3)wcsnrtombs(3)wcspbrk(3)wcsrchr(3)wcsrtombs(3)wcsspn(3)wcsstr(3)wcstoimax(3)wcstok(3)wcstombs(3)wcswidth(3)wctob(3)wctomb(3)wctrans(3)wctype(3)wcwidth(3)wmemchr(3)wmemcmp(3)wmemcpy(3)wmemmove(3)wmemset(3)wordexp(3)wprintf(3)xcrypt(3)xdr(3)y0(3)man-pages(7)pthreads(7)standards(7)