LCOV - code coverage report
Current view: top level - src/port - thread.c (source / functions) Hit Total Coverage
Test: PostgreSQL 15devel Lines: 2 5 40.0 %
Date: 2021-12-04 23:09:10 Functions: 1 1 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * thread.c
       4             :  *
       5             :  *        Prototypes and macros around system calls, used to help make
       6             :  *        threaded libraries reentrant and safe to use from threaded applications.
       7             :  *
       8             :  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
       9             :  *
      10             :  * src/port/thread.c
      11             :  *
      12             :  *-------------------------------------------------------------------------
      13             :  */
      14             : 
      15             : #include "c.h"
      16             : 
      17             : #include <pwd.h>
      18             : 
      19             : 
      20             : /*
      21             :  *  Threading sometimes requires specially-named versions of functions
      22             :  *  that return data in static buffers, like strerror_r() instead of
      23             :  *  strerror().  Other operating systems use pthread_setspecific()
      24             :  *  and pthread_getspecific() internally to allow standard library
      25             :  *  functions to return static data to threaded applications. And some
      26             :  *  operating systems have neither.
      27             :  *
      28             :  *  Additional confusion exists because many operating systems that
      29             :  *  use pthread_setspecific/pthread_getspecific() also have *_r versions
      30             :  *  of standard library functions for compatibility with operating systems
      31             :  *  that require them.  However, internally, these *_r functions merely
      32             :  *  call the thread-safe standard library functions.
      33             :  *
      34             :  *  For example, BSD/OS 4.3 uses Bind 8.2.3 for getpwuid().  Internally,
      35             :  *  getpwuid() calls pthread_setspecific/pthread_getspecific() to return
      36             :  *  static data to the caller in a thread-safe manner.  However, BSD/OS
      37             :  *  also has getpwuid_r(), which merely calls getpwuid() and shifts
      38             :  *  around the arguments to match the getpwuid_r() function declaration.
      39             :  *  Therefore, while BSD/OS has getpwuid_r(), it isn't required.  It also
      40             :  *  doesn't have strerror_r(), so we can't fall back to only using *_r
      41             :  *  functions for threaded programs.
      42             :  *
      43             :  *  The current setup is to try threading in this order:
      44             :  *
      45             :  *      use *_r function names if they exit
      46             :  *          (*_THREADSAFE=yes)
      47             :  *      use non-*_r functions if they are thread-safe
      48             :  *
      49             :  *  One thread-safe solution for gethostbyname() might be to use getaddrinfo().
      50             :  */
      51             : 
      52             : 
      53             : /*
      54             :  * Wrapper around getpwuid() or getpwuid_r() to mimic POSIX getpwuid_r()
      55             :  * behaviour, if that function is not available or required.
      56             :  *
      57             :  * Per POSIX, the possible cases are:
      58             :  * success: returns zero, *result is non-NULL
      59             :  * uid not found: returns zero, *result is NULL
      60             :  * error during lookup: returns an errno code, *result is NULL
      61             :  * (caller should *not* assume that the errno variable is set)
      62             :  */
      63             : #ifndef WIN32
      64             : int
      65       24376 : pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
      66             :            size_t buflen, struct passwd **result)
      67             : {
      68             : #if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETPWUID_R)
      69       24376 :     return getpwuid_r(uid, resultbuf, buffer, buflen, result);
      70             : #else
      71             :     /* no getpwuid_r() available, just use getpwuid() */
      72           0 :     errno = 0;
      73           0 :     *result = getpwuid(uid);
      74             :     /* paranoia: ensure we return zero on success */
      75           0 :     return (*result == NULL) ? errno : 0;
      76             : #endif
      77             : }
      78             : #endif
      79             : 
      80             : /*
      81             :  * Wrapper around gethostbyname() or gethostbyname_r() to mimic
      82             :  * POSIX gethostbyname_r() behaviour, if it is not available or required.
      83             :  * This function is called _only_ by our getaddrinfo() portability function.
      84             :  */
      85             : #ifndef HAVE_GETADDRINFO
      86             : int
      87             : pqGethostbyname(const char *name,
      88             :                 struct hostent *resultbuf,
      89             :                 char *buffer, size_t buflen,
      90             :                 struct hostent **result,
      91             :                 int *herrno)
      92             : {
      93             : #if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)
      94             : 
      95             :     /*
      96             :      * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
      97             :      * hostent *'
      98             :      */
      99             :     *result = gethostbyname_r(name, resultbuf, buffer, buflen, herrno);
     100             :     return (*result == NULL) ? -1 : 0;
     101             : #else
     102             : 
     103             :     /* no gethostbyname_r(), just use gethostbyname() */
     104             :     *result = gethostbyname(name);
     105             : 
     106             :     if (*result != NULL)
     107             :         *herrno = h_errno;
     108             : 
     109             :     if (*result != NULL)
     110             :         return 0;
     111             :     else
     112             :         return -1;
     113             : #endif
     114             : }
     115             : 
     116             : #endif

Generated by: LCOV version 1.14