As a general rule, functions that use only local variables are reentrant-safe; any usage of a global or a static data renders them unsafe. This is a key point: you can only call those functions in a signal handler that are documented as being reentrant-safe or signal-async-safe.
The man page on signal-safety(7) http://man7.org/linux/man-pages/man7/signal-safety.7.html provides details for this.
Among them, it publishes a list of (alphabetically ordered) functions that the POSIX.1 standard requires an implementation to guarantee are implemented as being async-signal-safe, (See man page version 4.12, dated 2017-03-13)
So the bottom line is this: from within a signal handler, you can only invoke the following:
- C library functions or system calls that are in the signal-safety(7) man page (do look it up)
- Within a third-party library, functions explicitly documented as being async-signal-safe
- Your own library or other functions that have been explicitly written to be async-signal-safe
Also, don't forget that your signal handler function itself must be reentrant-safe. Do not access application global or static variables within it.