Header And Logo

PostgreSQL
| The world's most advanced open source database.

Defines | Typedefs | Functions

port.h File Reference

#include <ctype.h>
#include <netdb.h>
#include <pwd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
Include dependency graph for port.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define PGINVALID_SOCKET   (-1)
#define IS_DIR_SEP(ch)   ((ch) == '/')
#define is_absolute_path(filename)
#define EXE   ""
#define DEVNULL   "/dev/null"
#define SYSTEMQUOTE   ""
#define TIMEZONE_GLOBAL   timezone
#define TZNAME_GLOBAL   tzname
#define closesocket   close
#define pgoff_t   off_t
#define fseeko(a, b, c)   fseek(a, b, c)
#define ftello(a)   ftell(a)
#define qsort(a, b, c, d)   pg_qsort(a,b,c,d)

Typedefs

typedef int pgsocket
typedef int(* qsort_arg_comparator )(const void *a, const void *b, void *arg)
typedef void(* pqsigfunc )(int signo)

Functions

bool pg_set_noblock (pgsocket sock)
bool pg_set_block (pgsocket sock)
bool has_drive_prefix (const char *filename)
char * first_dir_separator (const char *filename)
char * last_dir_separator (const char *filename)
char * first_path_var_separator (const char *pathlist)
void join_path_components (char *ret_path, const char *head, const char *tail)
void canonicalize_path (char *path)
void make_native_path (char *path)
bool path_contains_parent_reference (const char *path)
bool path_is_relative_and_below_cwd (const char *path)
bool path_is_prefix_of_path (const char *path1, const char *path2)
const char * get_progname (const char *argv0)
void get_share_path (const char *my_exec_path, char *ret_path)
void get_etc_path (const char *my_exec_path, char *ret_path)
void get_include_path (const char *my_exec_path, char *ret_path)
void get_pkginclude_path (const char *my_exec_path, char *ret_path)
void get_includeserver_path (const char *my_exec_path, char *ret_path)
void get_lib_path (const char *my_exec_path, char *ret_path)
void get_pkglib_path (const char *my_exec_path, char *ret_path)
void get_locale_path (const char *my_exec_path, char *ret_path)
void get_doc_path (const char *my_exec_path, char *ret_path)
void get_html_path (const char *my_exec_path, char *ret_path)
void get_man_path (const char *my_exec_path, char *ret_path)
bool get_home_path (char *ret_path)
void get_parent_directory (char *path)
char ** pgfnames (const char *path)
void pgfnames_cleanup (char **filenames)
void set_pglocale_pgservice (const char *argv0, const char *app)
int find_my_exec (const char *argv0, char *retpath)
int find_other_exec (const char *argv0, const char *target, const char *versionstr, char *retpath)
void pg_usleep (long microsec)
int pg_strcasecmp (const char *s1, const char *s2)
int pg_strncasecmp (const char *s1, const char *s2, size_t n)
unsigned char pg_toupper (unsigned char ch)
unsigned char pg_tolower (unsigned char ch)
unsigned char pg_ascii_toupper (unsigned char ch)
unsigned char pg_ascii_tolower (unsigned char ch)
char * simple_prompt (const char *prompt, int maxlen, bool echo)
int pclose_check (FILE *stream)
bool rmtree (const char *path, bool rmtopdir)
char * crypt (const char *key, const char *setting)
double pg_erand48 (unsigned short xseed[3])
long pg_lrand48 (void)
void pg_srand48 (long seed)
int fls (int mask)
int getopt (int nargc, char *const *nargv, const char *ostr)
int getpeereid (int sock, uid_t *uid, gid_t *gid)
int isinf (double x)
double rint (double x)
int inet_aton (const char *cp, struct in_addr *addr)
size_t strlcat (char *dst, const char *src, size_t siz)
size_t strlcpy (char *dst, const char *src, size_t siz)
long random (void)
void unsetenv (const char *name)
void srandom (unsigned int seed)
char * pqStrerror (int errnum, char *strerrbuf, size_t buflen)
int pqGetpwuid (uid_t uid, struct passwd *resultbuf, char *buffer, size_t buflen, struct passwd **result)
int pqGethostbyname (const char *name, struct hostent *resultbuf, char *buffer, size_t buflen, struct hostent **result, int *herrno)
void pg_qsort (void *base, size_t nel, size_t elsize, int(*cmp)(const void *, const void *))
int pg_qsort_strcmp (const void *a, const void *b)
void qsort_arg (void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
int pg_get_encoding_from_locale (const char *ctype, bool write_message)
char * inet_net_ntop (int af, const void *src, int bits, char *dst, size_t size)
int pg_check_dir (const char *dir)
int pg_mkdir_p (char *path, int omode)
pqsigfunc pqsignal (int signo, pqsigfunc func)
char * escape_single_quotes_ascii (const char *src)
char * wait_result_to_str (int exit_status)

Define Documentation

#define closesocket   close
#define DEVNULL   "/dev/null"
#define EXE   ""

Definition at line 108 of file port.h.

Referenced by find_other_exec(), and get_progname().

#define fseeko (   a,
  b,
  c 
)    fseek(a, b, c)

Definition at line 381 of file port.h.

#define ftello (   a  )     ftell(a)

Definition at line 382 of file port.h.

#define is_absolute_path (   filename  ) 
#define IS_DIR_SEP (   ch  )     ((ch) == '/')
#define PGINVALID_SOCKET   (-1)
#define pgoff_t   off_t

Definition at line 365 of file port.h.

#define qsort (   a,
  b,
  c,
  d 
)    pg_qsort(a,b,c,d)

Definition at line 445 of file port.h.

Referenced by _ltree_picksplit(), aclitemsort(), aclmembers(), acquire_sample_rows(), add_guc_variable(), AddEnumLabel(), associate(), build_guc_variables(), BuildEventTriggerCache(), buildIndexArray(), choose_bitmap_and(), compileTheLexeme(), compute_array_stats(), compute_range_stats(), compute_scalar_stats(), compute_tsvector_stats(), dsynonym_init(), eliminate_duplicate_dependencies(), entry_dealloc(), EnumValuesCreate(), fill_in_constant_lengths(), find_inheritance_children(), findObjectByCatalogId(), g_int_picksplit(), g_intbig_picksplit(), gbt_num_picksplit(), generate_trgm(), generate_wildcard_trgm(), get_docrep(), ghstore_picksplit(), ginGetBAEntry(), gist_box_picksplit(), gseg_picksplit(), gtrgm_picksplit(), gtsquery_picksplit(), gtsvector_picksplit(), hstoreUniquePairs(), load_enum_cache_data(), ltree_picksplit(), ltsGetFreeBlock(), mcelem_array_contained_selec(), mXactCacheGetBySet(), mXactCachePut(), NISortAffixes(), NISortDictionary(), packGraph(), PageIndexMultiDelete(), PageRepairFragmentation(), perform_base_backup(), pg_qsort(), ProcArrayApplyRecoveryInfo(), putVariable(), QTNSort(), range_gist_double_sorting_split(), read_dictionary(), readstoplist(), rebuild_database_list(), run_named_permutations(), selectColorTrigrams(), sort_pool(), sort_snapshot(), sortDataAndIndexObjectsBySize(), sortDumpableObjectsByTypeName(), sortDumpableObjectsByTypeOid(), spg_kd_picksplit(), spg_quad_picksplit(), spg_text_picksplit(), spgPageIndexMultiDelete(), tbm_begin_iterate(), TidListCreate(), uniqueint(), uniquePos(), uniqueWORD(), and writezone().

#define SYSTEMQUOTE   ""
#define TIMEZONE_GLOBAL   timezone

Definition at line 259 of file port.h.

Referenced by abstime2tm(), and timestamp2tm().

#define TZNAME_GLOBAL   tzname

Definition at line 260 of file port.h.

Referenced by abstime2tm(), and timestamp2tm().


Typedef Documentation

typedef int pgsocket

Definition at line 22 of file port.h.

typedef void(* pqsigfunc)(int signo)

Definition at line 466 of file port.h.

typedef int(* qsort_arg_comparator)(const void *a, const void *b, void *arg)

Definition at line 447 of file port.h.


Function Documentation

void canonicalize_path ( char *  path  ) 

Definition at line 216 of file path.c.

References skip_drive, trim_directory(), and trim_trailing_separator().

Referenced by adjust_data_dir(), check_canonical_path(), convert_and_check_filename(), create_script_for_old_cluster_deletion(), create_xlog_symlink(), CreateTableSpace(), do_copy(), exec_command(), find_in_dynamic_libpath(), find_my_exec(), find_other_exec(), load_libraries(), main(), make_absolute_path(), make_relative_path(), perform_fsync(), process_file(), resolve_symlinks(), set_pglocale_pgservice(), setup(), setup_bin_paths(), setup_pgdata(), SplitDirectoriesString(), and tokenize_inc_file().

{
    char       *p,
               *to_p;
    char       *spath;
    bool        was_sep = false;
    int         pending_strips;

#ifdef WIN32

    /*
     * The Windows command processor will accept suitably quoted paths with
     * forward slashes, but barfs badly with mixed forward and back slashes.
     */
    for (p = path; *p; p++)
    {
        if (*p == '\\')
            *p = '/';
    }

    /*
     * In Win32, if you do: prog.exe "a b" "\c\d\" the system will pass \c\d"
     * as argv[2], so trim off trailing quote.
     */
    if (p > path && *(p - 1) == '"')
        *(p - 1) = '/';
#endif

    /*
     * Removing the trailing slash on a path means we never get ugly double
     * trailing slashes. Also, Win32 can't stat() a directory with a trailing
     * slash. Don't remove a leading slash, though.
     */
    trim_trailing_separator(path);

    /*
     * Remove duplicate adjacent separators
     */
    p = path;
#ifdef WIN32
    /* Don't remove leading double-slash on Win32 */
    if (*p)
        p++;
#endif
    to_p = p;
    for (; *p; p++, to_p++)
    {
        /* Handle many adjacent slashes, like "/a///b" */
        while (*p == '/' && was_sep)
            p++;
        if (to_p != p)
            *to_p = *p;
        was_sep = (*p == '/');
    }
    *to_p = '\0';

    /*
     * Remove any trailing uses of "." and process ".." ourselves
     *
     * Note that "/../.." should reduce to just "/", while "../.." has to be
     * kept as-is.  In the latter case we put back mistakenly trimmed ".."
     * components below.  Also note that we want a Windows drive spec to be
     * visible to trim_directory(), but it's not part of the logic that's
     * looking at the name components; hence distinction between path and
     * spath.
     */
    spath = skip_drive(path);
    pending_strips = 0;
    for (;;)
    {
        int         len = strlen(spath);

        if (len >= 2 && strcmp(spath + len - 2, "/.") == 0)
            trim_directory(path);
        else if (strcmp(spath, ".") == 0)
        {
            /* Want to leave "." alone, but "./.." has to become ".." */
            if (pending_strips > 0)
                *spath = '\0';
            break;
        }
        else if ((len >= 3 && strcmp(spath + len - 3, "/..") == 0) ||
                 strcmp(spath, "..") == 0)
        {
            trim_directory(path);
            pending_strips++;
        }
        else if (pending_strips > 0 && *spath != '\0')
        {
            /* trim a regular directory name canceled by ".." */
            trim_directory(path);
            pending_strips--;
            /* foo/.. should become ".", not empty */
            if (*spath == '\0')
                strcpy(spath, ".");
        }
        else
            break;
    }

    if (pending_strips > 0)
    {
        /*
         * We could only get here if path is now totally empty (other than a
         * possible drive specifier on Windows). We have to put back one or
         * more ".."'s that we took off.
         */
        while (--pending_strips > 0)
            strcat(path, "../");
        strcat(path, "..");
    }
}

char* crypt ( const char *  key,
const char *  setting 
)

Referenced by chkpass_eq(), chkpass_in(), and chkpass_ne().

char* escape_single_quotes_ascii ( const char *  src  ) 

Definition at line 33 of file quotes.c.

References i, malloc, and SQL_STR_DOUBLE.

Referenced by escape_quotes().

{
    int         len = strlen(src),
                i,
                j;
    char       *result = malloc(len * 2 + 1);

    if (!result)
        return NULL;

    for (i = 0, j = 0; i < len; i++)
    {
        if (SQL_STR_DOUBLE(src[i], true))
            result[j++] = src[i];
        result[j++] = src[i];
    }
    result[j] = '\0';
    return result;
}

int find_my_exec ( const char *  argv0,
char *  retpath 
)

Definition at line 119 of file exec.c.

References _, canonicalize_path(), first_dir_separator(), first_path_var_separator(), is_absolute_path, join_path_components(), log_error, MAXPGPATH, Min, NULL, resolve_symlinks(), strerror(), StrNCpy, and validate_exec().

Referenced by AuxiliaryProcessMain(), find_other_exec(), find_other_exec_or_die(), getInstallationPaths(), main(), PostgresMain(), process_psqlrc(), set_pglocale_pgservice(), setup(), and setup_bin_paths().

{
    char        cwd[MAXPGPATH],
                test_path[MAXPGPATH];
    char       *path;

    if (!getcwd(cwd, MAXPGPATH))
    {
        log_error(_("could not identify current directory: %s"),
                  strerror(errno));
        return -1;
    }

    /*
     * If argv0 contains a separator, then PATH wasn't used.
     */
    if (first_dir_separator(argv0) != NULL)
    {
        if (is_absolute_path(argv0))
            StrNCpy(retpath, argv0, MAXPGPATH);
        else
            join_path_components(retpath, cwd, argv0);
        canonicalize_path(retpath);

        if (validate_exec(retpath) == 0)
            return resolve_symlinks(retpath);

        log_error(_("invalid binary \"%s\""), retpath);
        return -1;
    }

#ifdef WIN32
    /* Win32 checks the current directory first for names without slashes */
    join_path_components(retpath, cwd, argv0);
    if (validate_exec(retpath) == 0)
        return resolve_symlinks(retpath);
#endif

    /*
     * Since no explicit path was supplied, the user must have been relying on
     * PATH.  We'll search the same PATH.
     */
    if ((path = getenv("PATH")) && *path)
    {
        char       *startp = NULL,
                   *endp = NULL;

        do
        {
            if (!startp)
                startp = path;
            else
                startp = endp + 1;

            endp = first_path_var_separator(startp);
            if (!endp)
                endp = startp + strlen(startp); /* point to end */

            StrNCpy(test_path, startp, Min(endp - startp + 1, MAXPGPATH));

            if (is_absolute_path(test_path))
                join_path_components(retpath, test_path, argv0);
            else
            {
                join_path_components(retpath, cwd, test_path);
                join_path_components(retpath, retpath, argv0);
            }
            canonicalize_path(retpath);

            switch (validate_exec(retpath))
            {
                case 0: /* found ok */
                    return resolve_symlinks(retpath);
                case -1:        /* wasn't even a candidate, keep looking */
                    break;
                case -2:        /* found but disqualified */
                    log_error(_("could not read binary \"%s\""),
                              retpath);
                    break;
            }
        } while (*endp);
    }

    log_error(_("could not find a \"%s\" to execute"), argv0);
    return -1;
}

int find_other_exec ( const char *  argv0,
const char *  target,
const char *  versionstr,
char *  retpath 
)

Definition at line 307 of file exec.c.

References canonicalize_path(), EXE, find_my_exec(), last_dir_separator(), MAXPGPATH, pipe_read_line(), snprintf(), and validate_exec().

Referenced by find_other_exec_or_die(), getInstallationPaths(), main(), and setup_bin_paths().

{
    char        cmd[MAXPGPATH];
    char        line[100];

    if (find_my_exec(argv0, retpath) < 0)
        return -1;

    /* Trim off program name and keep just directory */
    *last_dir_separator(retpath) = '\0';
    canonicalize_path(retpath);

    /* Now append the other program's name */
    snprintf(retpath + strlen(retpath), MAXPGPATH - strlen(retpath),
             "/%s%s", target, EXE);

    if (validate_exec(retpath) != 0)
        return -1;

    snprintf(cmd, sizeof(cmd), "\"%s\" -V", retpath);

    if (!pipe_read_line(cmd, line, sizeof(line)))
        return -1;

    if (strcmp(line, versionstr) != 0)
        return -2;

    return 0;
}

char* first_dir_separator ( const char *  filename  ) 
char* first_path_var_separator ( const char *  pathlist  ) 

Definition at line 112 of file path.c.

References IS_PATH_VAR_SEP.

Referenced by find_in_dynamic_libpath(), and find_my_exec().

{
    const char *p;

    /* skip_drive is not needed */
    for (p = pathlist; *p; p++)
        if (IS_PATH_VAR_SEP(*p))
            return (char *) p;
    return NULL;
}

int fls ( int  mask  ) 

Definition at line 55 of file fls.c.

Referenced by interval_transform().

{
    int         bit;

    if (mask == 0)
        return (0);
    for (bit = 1; mask != 1; bit++)
        mask = (unsigned int) mask >> 1;
    return (bit);
}

void get_doc_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 630 of file path.c.

References make_relative_path().

Referenced by show_docdir().

{
    make_relative_path(ret_path, DOCDIR, PGBINDIR, my_exec_path);
}

void get_etc_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 567 of file path.c.

References make_relative_path().

Referenced by process_psqlrc(), set_pglocale_pgservice(), and show_sysconfdir().

{
    make_relative_path(ret_path, SYSCONFDIR, PGBINDIR, my_exec_path);
}

bool get_home_path ( char *  ret_path  ) 

Definition at line 661 of file path.c.

References MAXPGPATH, pqGetpwuid(), snprintf(), and strlcpy().

Referenced by expand_tilde(), initializeInput(), and process_psqlrc().

{
#ifndef WIN32
    char        pwdbuf[BUFSIZ];
    struct passwd pwdstr;
    struct passwd *pwd = NULL;

    if (pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) != 0)
        return false;
    strlcpy(ret_path, pwd->pw_dir, MAXPGPATH);
    return true;
#else
    char       *tmppath;

    /*
     * Note: We use getenv here because the more modern
     * SHGetSpecialFolderPath() will force us to link with shell32.lib which
     * eats valuable desktop heap.
     */
    tmppath = getenv("APPDATA");
    if (!tmppath)
        return false;
    snprintf(ret_path, MAXPGPATH, "%s/postgresql", tmppath);
    return true;
#endif
}

void get_html_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 639 of file path.c.

References make_relative_path().

Referenced by show_htmldir().

{
    make_relative_path(ret_path, HTMLDIR, PGBINDIR, my_exec_path);
}

void get_include_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 576 of file path.c.

References make_relative_path().

Referenced by main(), and show_includedir().

{
    make_relative_path(ret_path, INCLUDEDIR, PGBINDIR, my_exec_path);
}

void get_includeserver_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 594 of file path.c.

References make_relative_path().

Referenced by show_includedir_server().

{
    make_relative_path(ret_path, INCLUDEDIRSERVER, PGBINDIR, my_exec_path);
}

void get_lib_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 603 of file path.c.

References make_relative_path().

Referenced by show_libdir().

{
    make_relative_path(ret_path, LIBDIR, PGBINDIR, my_exec_path);
}

void get_locale_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 621 of file path.c.

References make_relative_path().

Referenced by pg_bindtextdomain(), set_pglocale_pgservice(), and show_localedir().

{
    make_relative_path(ret_path, LOCALEDIR, PGBINDIR, my_exec_path);
}

void get_man_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 648 of file path.c.

References make_relative_path().

Referenced by show_mandir().

{
    make_relative_path(ret_path, MANDIR, PGBINDIR, my_exec_path);
}

void get_parent_directory ( char *  path  ) 
void get_pkginclude_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 585 of file path.c.

References make_relative_path().

Referenced by main(), and show_pkgincludedir().

{
    make_relative_path(ret_path, PKGINCLUDEDIR, PGBINDIR, my_exec_path);
}

void get_pkglib_path ( const char *  my_exec_path,
char *  ret_path 
)

Definition at line 612 of file path.c.

References make_relative_path().

Referenced by getInstallationPaths(), PostgresMain(), show_pgxs(), and show_pkglibdir().

{
    make_relative_path(ret_path, PKGLIBDIR, PGBINDIR, my_exec_path);
}

const char* get_progname ( const char *  argv0  ) 

Definition at line 415 of file path.c.

References EXE, last_dir_separator(), NULL, pg_strcasecmp(), progname, and skip_drive.

Referenced by get_opts(), handle_help_version_opts(), main(), parseCommandLine(), and regression_main().

{
    const char *nodir_name;
    char       *progname;

    nodir_name = last_dir_separator(argv0);
    if (nodir_name)
        nodir_name++;
    else
        nodir_name = skip_drive(argv0);

    /*
     * Make a copy in case argv[0] is modified by ps_status. Leaks memory, but
     * called only once.
     */
    progname = strdup(nodir_name);
    if (progname == NULL)
    {
        fprintf(stderr, "%s: out of memory\n", nodir_name);
        abort();                /* This could exit the postmaster */
    }

#if defined(__CYGWIN__) || defined(WIN32)
    /* strip ".exe" suffix, regardless of case */
    if (strlen(progname) > sizeof(EXE) - 1 &&
    pg_strcasecmp(progname + strlen(progname) - (sizeof(EXE) - 1), EXE) == 0)
        progname[strlen(progname) - (sizeof(EXE) - 1)] = '\0';
#endif

    return progname;
}

void get_share_path ( const char *  my_exec_path,
char *  ret_path 
)
int getopt ( int  nargc,
char *const *  nargv,
const char *  ostr 
)

Definition at line 77 of file getopt.c.

References optarg, opterr, optind, and optopt.

Referenced by AuxiliaryProcessMain(), get_opts(), main(), PostmasterMain(), and process_postgres_switches().

{
    static char *place = EMSG;  /* option letter processing */
    char       *oli;            /* option letter list index */

    if (!*place)
    {                           /* update scanning pointer */
        if (optind >= nargc || *(place = nargv[optind]) != '-')
        {
            place = EMSG;
            return -1;
        }
        if (place[1] && *++place == '-' && place[1] == '\0')
        {                       /* found "--" */
            ++optind;
            place = EMSG;
            return -1;
        }
    }                           /* option letter okay? */
    if ((optopt = (int) *place++) == (int) ':' ||
        !(oli = strchr(ostr, optopt)))
    {
        /*
         * if the user didn't specify '-' as an option, assume it means -1.
         */
        if (optopt == (int) '-')
        {
            place = EMSG;
            return -1;
        }
        if (!*place)
            ++optind;
        if (opterr && *ostr != ':')
            (void) fprintf(stderr,
                           "illegal option -- %c\n", optopt);
        return BADCH;
    }
    if (*++oli != ':')
    {                           /* don't need argument */
        optarg = NULL;
        if (!*place)
            ++optind;
    }
    else
    {                           /* need an argument */
        if (*place)             /* no white space */
            optarg = place;
        else if (nargc <= ++optind)
        {                       /* no arg */
            place = EMSG;
            if (*ostr == ':')
                return BADARG;
            if (opterr)
                (void) fprintf(stderr,
                               "option requires an argument -- %c\n",
                               optopt);
            return BADCH;
        }
        else
            /* white space */
            optarg = nargv[optind];
        place = EMSG;
        ++optind;
    }
    return optopt;              /* dump back option letter */
}

int getpeereid ( int  sock,
uid_t uid,
gid_t gid 
)

Definition at line 35 of file getpeereid.c.

Referenced by PQconnectPoll().

{
#if defined(SO_PEERCRED)
    /* Linux: use getsockopt(SO_PEERCRED) */
    struct ucred peercred;
    ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);

    if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0 ||
        so_len != sizeof(peercred))
        return -1;
    *uid = peercred.uid;
    *gid = peercred.gid;
    return 0;
#elif defined(LOCAL_PEERCRED)
    /* Debian with FreeBSD kernel: use getsockopt(LOCAL_PEERCRED) */
    struct xucred peercred;
    ACCEPT_TYPE_ARG3 so_len = sizeof(peercred);

    if (getsockopt(sock, 0, LOCAL_PEERCRED, &peercred, &so_len) != 0 ||
        so_len != sizeof(peercred) ||
        peercred.cr_version != XUCRED_VERSION)
        return -1;
    *uid = peercred.cr_uid;
    *gid = peercred.cr_gid;
    return 0;
#elif defined(HAVE_GETPEERUCRED)
    /* Solaris: use getpeerucred() */
    ucred_t    *ucred;

    ucred = NULL;               /* must be initialized to NULL */
    if (getpeerucred(sock, &ucred) == -1)
        return -1;

    *uid = ucred_geteuid(ucred);
    *gid = ucred_getegid(ucred);
    ucred_free(ucred);

    if (*uid == (uid_t) (-1) || *gid == (gid_t) (-1))
        return -1;
    return 0;
#else
    /* No implementation available on this platform */
    errno = ENOSYS;
    return -1;
#endif
}

bool has_drive_prefix ( const char *  filename  ) 

Definition at line 83 of file path.c.

References skip_drive.

Referenced by process_file().

{
    return skip_drive(path) != path;
}

int inet_aton ( const char *  cp,
struct in_addr *  addr 
)

Definition at line 54 of file inet_aton.c.

References val.

Referenced by getaddrinfo().

{
    unsigned int val;
    int         base,
                n;
    char        c;
    u_int       parts[4];
    u_int      *pp = parts;

    for (;;)
    {
        /*
         * Collect number up to ``.''. Values are specified as for C: 0x=hex,
         * 0=octal, other=decimal.
         */
        val = 0;
        base = 10;
        if (*cp == '0')
        {
            if (*++cp == 'x' || *cp == 'X')
                base = 16, cp++;
            else
                base = 8;
        }
        while ((c = *cp) != '\0')
        {
            if (isdigit((unsigned char) c))
            {
                val = (val * base) + (c - '0');
                cp++;
                continue;
            }
            if (base == 16 && isxdigit((unsigned char) c))
            {
                val = (val << 4) +
                    (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
                cp++;
                continue;
            }
            break;
        }
        if (*cp == '.')
        {
            /*
             * Internet format: a.b.c.d a.b.c   (with c treated as 16-bits)
             * a.b     (with b treated as 24 bits)
             */
            if (pp >= parts + 3 || val > 0xff)
                return 0;
            *pp++ = val, cp++;
        }
        else
            break;
    }

    /*
     * Check for trailing junk.
     */
    while (*cp)
        if (!isspace((unsigned char) *cp++))
            return 0;

    /*
     * Concoct the address according to the number of parts specified.
     */
    n = pp - parts + 1;
    switch (n)
    {

        case 1:         /* a -- 32 bits */
            break;

        case 2:         /* a.b -- 8.24 bits */
            if (val > 0xffffff)
                return 0;
            val |= parts[0] << 24;
            break;

        case 3:         /* a.b.c -- 8.8.16 bits */
            if (val > 0xffff)
                return 0;
            val |= (parts[0] << 24) | (parts[1] << 16);
            break;

        case 4:         /* a.b.c.d -- 8.8.8.8 bits */
            if (val > 0xff)
                return 0;
            val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
            break;
    }
    if (addr)
        addr->s_addr = htonl(val);
    return 1;
}

char* inet_net_ntop ( int  af,
const void *  src,
int  bits,
char *  dst,
size_t  size 
)

Definition at line 78 of file inet_net_ntop.c.

References inet_net_ntop_ipv4(), inet_net_ntop_ipv6(), NULL, PGSQL_AF_INET, and PGSQL_AF_INET6.

Referenced by connectFailureMessage(), getnameinfo(), inet_abbrev(), network_host(), network_out(), and network_show().

{
    /*
     * We need to cover both the address family constants used by the PG inet
     * type (PGSQL_AF_INET and PGSQL_AF_INET6) and those used by the system
     * libraries (AF_INET and AF_INET6).  We can safely assume PGSQL_AF_INET
     * == AF_INET, but the INET6 constants are very likely to be different. If
     * AF_INET6 isn't defined, silently ignore it.
     */
    switch (af)
    {
        case PGSQL_AF_INET:
            return (inet_net_ntop_ipv4(src, bits, dst, size));
        case PGSQL_AF_INET6:
#if defined(AF_INET6) && AF_INET6 != PGSQL_AF_INET6
        case AF_INET6:
#endif
            return (inet_net_ntop_ipv6(src, bits, dst, size));
        default:
            errno = EAFNOSUPPORT;
            return (NULL);
    }
}

int isinf ( double  x  ) 
void join_path_components ( char *  ret_path,
const char *  head,
const char *  tail 
)

Definition at line 180 of file path.c.

References IS_DIR_SEP, MAXPGPATH, skip_drive, snprintf(), and strlcpy().

Referenced by find_my_exec(), make_relative_path(), process_file(), resolve_symlinks(), and tokenize_inc_file().

{
    if (ret_path != head)
        strlcpy(ret_path, head, MAXPGPATH);

    /*
     * Remove any leading "." in the tail component.
     *
     * Note: we used to try to remove ".." as well, but that's tricky to get
     * right; now we just leave it to be done by canonicalize_path() later.
     */
    while (tail[0] == '.' && IS_DIR_SEP(tail[1]))
        tail += 2;

    if (*tail)
    {
        /* only separate with slash if head wasn't empty */
        snprintf(ret_path + strlen(ret_path), MAXPGPATH - strlen(ret_path),
                 "%s%s",
                 (*(skip_drive(head)) != '\0') ? "/" : "",
                 tail);
    }
}

char* last_dir_separator ( const char *  filename  ) 

Definition at line 130 of file path.c.

References IS_DIR_SEP, and skip_drive.

Referenced by ECPGconnect(), find_other_exec(), get_progname(), main(), resolve_symlinks(), setup(), and setup_bin_paths().

{
    const char *p,
               *ret = NULL;

    for (p = skip_drive(filename); *p; p++)
        if (IS_DIR_SEP(*p))
            ret = p;
    return (char *) ret;
}

void make_native_path ( char *  path  ) 

Definition at line 158 of file path.c.

Referenced by pgarch_archiveXlog(), and RestoreArchivedFile().

{
#ifdef WIN32
    char       *p;

    for (p = filename; *p; p++)
        if (*p == '/')
            *p = '\\';
#endif
}

bool path_contains_parent_reference ( const char *  path  ) 

Definition at line 338 of file path.c.

References NULL, and skip_drive.

Referenced by convert_and_check_filename(), and path_is_relative_and_below_cwd().

{
    int         path_len;

    path = skip_drive(path);    /* C: shouldn't affect our conclusion */

    path_len = strlen(path);

    /*
     * ".." could be the whole path; otherwise, if it's present it must be at
     * the beginning, in the middle, or at the end.
     */
    if (strcmp(path, "..") == 0 ||
        strncmp(path, "../", 3) == 0 ||
        strstr(path, "/../") != NULL ||
        (path_len >= 3 && strcmp(path + path_len - 3, "/..") == 0))
        return true;

    return false;
}

bool path_is_prefix_of_path ( const char *  path1,
const char *  path2 
)

Definition at line 400 of file path.c.

References IS_DIR_SEP.

Referenced by convert_and_check_filename(), and create_script_for_old_cluster_deletion().

{
    int         path1_len = strlen(path1);

    if (strncmp(path1, path2, path1_len) == 0 &&
        (IS_DIR_SEP(path2[path1_len]) || path2[path1_len] == '\0'))
        return true;
    return false;
}

bool path_is_relative_and_below_cwd ( const char *  path  ) 

Definition at line 367 of file path.c.

References is_absolute_path, IS_DIR_SEP, and path_contains_parent_reference().

Referenced by convert_and_check_filename().

{
    if (is_absolute_path(path))
        return false;
    /* don't allow anything above the cwd */
    else if (path_contains_parent_reference(path))
        return false;
#ifdef WIN32

    /*
     * On Win32, a drive letter _not_ followed by a slash, e.g. 'E:abc', is
     * relative to the cwd on that drive, or the drive's root directory if
     * that drive has no cwd.  Because the path itself cannot tell us which is
     * the case, we have to assume the worst, i.e. that it is not below the
     * cwd.  We could use GetFullPathName() to find the full path but that
     * could change if the current directory for the drive changes underneath
     * us, so we just disallow it.
     */
    else if (isalpha((unsigned char) path[0]) && path[1] == ':' &&
             !IS_DIR_SEP(path[2]))
        return false;
#endif
    else
        return true;
}

int pclose_check ( FILE *  stream  ) 

Definition at line 510 of file exec.c.

References _, free, log_error, pfree(), strerror(), and wait_result_to_str().

Referenced by pipe_read_line().

{
    int         exitstatus;
    char       *reason;

    exitstatus = pclose(stream);

    if (exitstatus == 0)
        return 0;               /* all is well */

    if (exitstatus == -1)
    {
        /* pclose() itself failed, and hopefully set errno */
        log_error(_("pclose failed: %s"), strerror(errno));
    }
    else
    {
        reason = wait_result_to_str(exitstatus);
        log_error("%s", reason);
#ifdef FRONTEND
        free(reason);
#else
        pfree(reason);
#endif
    }
    return exitstatus;
}

unsigned char pg_ascii_tolower ( unsigned char  ch  ) 

Definition at line 146 of file pgstrcasecmp.c.

Referenced by asc_initcap(), asc_tolower(), pg_wc_tolower(), and SB_lower_char().

{
    if (ch >= 'A' && ch <= 'Z')
        ch += 'a' - 'A';
    return ch;
}

unsigned char pg_ascii_toupper ( unsigned char  ch  ) 

Definition at line 135 of file pgstrcasecmp.c.

Referenced by asc_initcap(), asc_toupper(), filter_list_to_array(), and pg_wc_toupper().

{
    if (ch >= 'a' && ch <= 'z')
        ch += 'A' - 'a';
    return ch;
}

int pg_check_dir ( const char *  dir  ) 

Definition at line 29 of file pgcheckdir.c.

References closedir(), dirent::d_name, NULL, opendir(), and readdir().

Referenced by create_data_directory(), create_xlog_symlink(), and verify_dir_is_empty_or_create().

{
    int         result = 1;
    DIR        *chkdir;
    struct dirent *file;
    bool        dot_found = false;

    errno = 0;

    chkdir = opendir(dir);

    if (chkdir == NULL)
        return (errno == ENOENT) ? 0 : -1;

    while ((file = readdir(chkdir)) != NULL)
    {
        if (strcmp(".", file->d_name) == 0 ||
            strcmp("..", file->d_name) == 0)
        {
            /* skip this and parent directory */
            continue;
        }
#ifndef WIN32
        /* file starts with "." */
        else if (file->d_name[0] == '.')
        {
            dot_found = true;
        }
        else if (strcmp("lost+found", file->d_name) == 0)
        {
            result = 3;         /* not empty, mount point */
            break;
        }
#endif
        else
        {
            result = 4;         /* not empty */
            break;
        }
    }

#ifdef WIN32
    /*
     * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
     * released version
     */
    if (GetLastError() == ERROR_NO_MORE_FILES)
        errno = 0;
#endif

    closedir(chkdir);

    if (errno != 0)
        result = -1;            /* some kind of I/O error? */

    /* We report on dot-files if we _only_ find dot files */
    if (result == 1 && dot_found)
        result = 2;

    return result;
}

double pg_erand48 ( unsigned short  xseed[3]  ) 

Definition at line 79 of file erand48.c.

References _dorand48().

Referenced by doCustom(), geqo_rand(), and getrand().

{
    _dorand48(xseed);
    return ldexp((double) xseed[0], -48) +
        ldexp((double) xseed[1], -32) +
        ldexp((double) xseed[2], -16);
}

int pg_get_encoding_from_locale ( const char *  ctype,
bool  write_message 
)
long pg_lrand48 ( void   ) 

Definition at line 88 of file erand48.c.

References _dorand48(), and _rand48_seed.

Referenced by random().

{
    _dorand48(_rand48_seed);
    return ((long) _rand48_seed[2] << 15) + ((long) _rand48_seed[1] >> 1);
}

int pg_mkdir_p ( char *  path,
int  omode 
)

Definition at line 57 of file pgmkdirp.c.

References mkdir, NULL, S_IRWXG, and S_IRWXO.

Referenced by create_xlog_symlink(), mkdatadir(), and verify_dir_is_empty_or_create().

{
    struct stat sb;
    mode_t      numask,
                oumask;
    int         last,
                retval;
    char       *p;

    retval = 0;
    p = path;

#ifdef WIN32
    /* skip network and drive specifiers for win32 */
    if (strlen(p) >= 2)
    {
        if (p[0] == '/' && p[1] == '/')
        {
            /* network drive */
            p = strstr(p + 2, "/");
            if (p == NULL)
            {
                errno = EINVAL;
                return -1;
            }
        }
        else if (p[1] == ':' &&
                 ((p[0] >= 'a' && p[0] <= 'z') ||
                  (p[0] >= 'A' && p[0] <= 'Z')))
        {
            /* local drive */
            p += 2;
        }
    }
#endif

    /*
     * POSIX 1003.2: For each dir operand that does not name an existing
     * directory, effects equivalent to those caused by the following command
     * shall occcur:
     *
     * mkdir -p -m $(umask -S),u+wx $(dirname dir) && mkdir [-m mode] dir
     *
     * We change the user's umask and then restore it, instead of doing
     * chmod's.  Note we assume umask() can't change errno.
     */
    oumask = umask(0);
    numask = oumask & ~(S_IWUSR | S_IXUSR);
    (void) umask(numask);

    if (p[0] == '/')            /* Skip leading '/'. */
        ++p;
    for (last = 0; !last; ++p)
    {
        if (p[0] == '\0')
            last = 1;
        else if (p[0] != '/')
            continue;
        *p = '\0';
        if (!last && p[1] == '\0')
            last = 1;

        if (last)
            (void) umask(oumask);

        /* check for pre-existing directory */
        if (stat(path, &sb) == 0)
        {
            if (!S_ISDIR(sb.st_mode))
            {
                if (last)
                    errno = EEXIST;
                else
                    errno = ENOTDIR;
                retval = -1;
                break;
            }
        }
        else if (mkdir(path, last ? omode : S_IRWXU | S_IRWXG | S_IRWXO) < 0)
        {
            retval = -1;
            break;
        }
        if (!last)
            *p = '/';
    }

    /* ensure we restored umask */
    (void) umask(oumask);

    return retval;
}

void pg_qsort ( void *  base,
size_t  nel,
size_t  elsize,
int(*)(const void *, const void *)  cmp 
)

Definition at line 103 of file qsort.c.

References cmp(), med3(), Min, qsort, swap, SWAPINIT, and vecswap.

Referenced by DropRelFileNodesAllBuffers().

{
    char       *pa,
               *pb,
               *pc,
               *pd,
               *pl,
               *pm,
               *pn;
    int         d,
                r,
                swaptype,
                presorted;

loop:SWAPINIT(a, es);
    if (n < 7)
    {
        for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
            for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
                 pl -= es)
                swap(pl, pl - es);
        return;
    }
    presorted = 1;
    for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
    {
        if (cmp(pm - es, pm) > 0)
        {
            presorted = 0;
            break;
        }
    }
    if (presorted)
        return;
    pm = (char *) a + (n / 2) * es;
    if (n > 7)
    {
        pl = (char *) a;
        pn = (char *) a + (n - 1) * es;
        if (n > 40)
        {
            d = (n / 8) * es;
            pl = med3(pl, pl + d, pl + 2 * d, cmp);
            pm = med3(pm - d, pm, pm + d, cmp);
            pn = med3(pn - 2 * d, pn - d, pn, cmp);
        }
        pm = med3(pl, pm, pn, cmp);
    }
    swap(a, pm);
    pa = pb = (char *) a + es;
    pc = pd = (char *) a + (n - 1) * es;
    for (;;)
    {
        while (pb <= pc && (r = cmp(pb, a)) <= 0)
        {
            if (r == 0)
            {
                swap(pa, pb);
                pa += es;
            }
            pb += es;
        }
        while (pb <= pc && (r = cmp(pc, a)) >= 0)
        {
            if (r == 0)
            {
                swap(pc, pd);
                pd -= es;
            }
            pc -= es;
        }
        if (pb > pc)
            break;
        swap(pb, pc);
        pb += es;
        pc -= es;
    }
    pn = (char *) a + n * es;
    r = Min(pa - (char *) a, pb - pa);
    vecswap(a, pb - r, r);
    r = Min(pd - pc, pn - pd - es);
    vecswap(pb, pn - r, r);
    if ((r = pb - pa) > es)
        qsort(a, r / es, es, cmp);
    if ((r = pd - pc) > es)
    {
        /* Iterate rather than recurse to save stack space */
        a = pn - r;
        n = r / es;
        goto loop;
    }
/*      qsort(pn - r, r / es, es, cmp);*/
}

int pg_qsort_strcmp ( const void *  a,
const void *  b 
)

Definition at line 201 of file qsort.c.

Referenced by BuildEventTriggerCache(), filter_event_trigger(), readstoplist(), and searchstoplist().

{
    return strcmp(*(char *const *) a, *(char *const *) b);
}

bool pg_set_block ( pgsocket  sock  ) 

Definition at line 35 of file noblock.c.

Referenced by pq_set_nonblocking().

{
#if !defined(WIN32)
    int         flags;

    flags = fcntl(sock, F_GETFL);
    if (flags < 0 || fcntl(sock, F_SETFL, (long) (flags & ~O_NONBLOCK)))
        return false;
    return true;
#else
    unsigned long ioctlsocket_ret = 0;

    /* Returns non-0 on failure, while fcntl() returns -1 on failure */
    return (ioctlsocket(sock, FIONBIO, &ioctlsocket_ret) == 0);
#endif
}

bool pg_set_noblock ( pgsocket  sock  ) 

Definition at line 21 of file noblock.c.

Referenced by pgstat_init(), pq_set_nonblocking(), PQconnectPoll(), and report_fork_failure_to_client().

{
#if !defined(WIN32)
    return (fcntl(sock, F_SETFL, O_NONBLOCK) != -1);
#else
    unsigned long ioctlsocket_ret = 1;

    /* Returns non-0 on failure, while fcntl() returns -1 on failure */
    return (ioctlsocket(sock, FIONBIO, &ioctlsocket_ret) == 0);
#endif
}

void pg_srand48 ( long  seed  ) 

Definition at line 95 of file erand48.c.

References _rand48_add, _rand48_mult, and _rand48_seed.

Referenced by srandom().

{
    _rand48_seed[0] = RAND48_SEED_0;
    _rand48_seed[1] = (unsigned short) seed;
    _rand48_seed[2] = (unsigned short) (seed >> 16);
    _rand48_mult[0] = RAND48_MULT_0;
    _rand48_mult[1] = RAND48_MULT_1;
    _rand48_mult[2] = RAND48_MULT_2;
    _rand48_add = RAND48_ADD;
}

int pg_strcasecmp ( const char *  s1,
const char *  s2 
)

Definition at line 36 of file pgstrcasecmp.c.

References IS_HIGHBIT_SET.

Referenced by AlterTSDictionary(), array_out(), ATExecSetStorage(), build_startup_packet(), check_datestyle(), check_ddl_tag(), check_ident_usermap(), check_locale_and_encoding(), check_log_destination(), check_usermap(), compat_find_digest(), compute_attributes_with_style(), config_enum_lookup_by_name(), convert_any_priv_string(), convert_priv_string(), defGetBoolean(), defGetTypeLength(), DefineAggregate(), DefineCollation(), DefineOperator(), DefineRange(), DefineTSConfiguration(), DefineTSDictionary(), DefineTSParser(), DefineTSTemplate(), DefineType(), dintdict_init(), dispell_init(), do_pset(), doCustom(), dsimple_init(), dsnowball_init(), dsynonym_init(), dumpFunc(), dxsyn_init(), echo_hidden_hook(), exec_command(), fillRelOptions(), find_matching_ts_config(), findTTStatus(), get_progname(), helpSQL(), hostname_match(), interpretOidsOption(), locate_stem_module(), main(), makeAlterConfigCommand(), on_error_rollback_hook(), parse_hstore(), parse_slash_copy(), parseArchiveFormat(), parseNameAndArgTypes(), ParseVariableBool(), pg_bind_textdomain_codeset(), pg_fe_sendauth(), pg_find_encoding(), pg_get_functiondef(), pgp_get_cipher_code(), pgp_get_digest_code(), PGTYPEStimestamp_defmt_scan(), plperl_trigger_handler(), PLy_exec_trigger(), pqSetenvPoll(), process_commands(), prsd_headline(), px_find_digest(), px_gen_salt(), px_resolve_alias(), ReadArrayStr(), splitTzLine(), SyncRepGetStandbyPriority(), thesaurus_init(), transformRelOptions(), unaccent_init(), validate_exec(), and xmlpi().

{
    for (;;)
    {
        unsigned char ch1 = (unsigned char) *s1++;
        unsigned char ch2 = (unsigned char) *s2++;

        if (ch1 != ch2)
        {
            if (ch1 >= 'A' && ch1 <= 'Z')
                ch1 += 'a' - 'A';
            else if (IS_HIGHBIT_SET(ch1) && isupper(ch1))
                ch1 = tolower(ch1);

            if (ch2 >= 'A' && ch2 <= 'Z')
                ch2 += 'a' - 'A';
            else if (IS_HIGHBIT_SET(ch2) && isupper(ch2))
                ch2 = tolower(ch2);

            if (ch1 != ch2)
                return (int) ch1 - (int) ch2;
        }
        if (ch1 == 0)
            break;
    }
    return 0;
}

int pg_strncasecmp ( const char *  s1,
const char *  s2,
size_t  n 
)

Definition at line 69 of file pgstrcasecmp.c.

References IS_HIGHBIT_SET.

Referenced by check_datestyle(), check_ddl_tag(), check_special_value(), check_timezone(), command_no_begin(), do_pset(), float4in(), float8in(), helpSQL(), is_select_command(), MainLoop(), map_sql_identifier_to_xml_name(), numeric_in(), parse_bool_with_len(), parseRelOptions(), ParseTzFile(), ParseVariableBool(), range_parse(), scan_directory_ci(), set_var_from_str(), SpecialTags(), and transformRelOptions().

{
    while (n-- > 0)
    {
        unsigned char ch1 = (unsigned char) *s1++;
        unsigned char ch2 = (unsigned char) *s2++;

        if (ch1 != ch2)
        {
            if (ch1 >= 'A' && ch1 <= 'Z')
                ch1 += 'a' - 'A';
            else if (IS_HIGHBIT_SET(ch1) && isupper(ch1))
                ch1 = tolower(ch1);

            if (ch2 >= 'A' && ch2 <= 'Z')
                ch2 += 'a' - 'A';
            else if (IS_HIGHBIT_SET(ch2) && isupper(ch2))
                ch2 = tolower(ch2);

            if (ch1 != ch2)
                return (int) ch1 - (int) ch2;
        }
        if (ch1 == 0)
            break;
    }
    return 0;
}

unsigned char pg_tolower ( unsigned char  ch  ) 

Definition at line 122 of file pgstrcasecmp.c.

References IS_HIGHBIT_SET.

Referenced by dir_strcmp(), ParseDateTime(), PGTYPESdate_defmt_asc(), PQfnumber(), processSQLNamePattern(), SB_lower_char(), seq_search(), str_initcap(), str_tolower(), and validateTzEntry().

{
    if (ch >= 'A' && ch <= 'Z')
        ch += 'a' - 'A';
    else if (IS_HIGHBIT_SET(ch) && isupper(ch))
        ch = tolower(ch);
    return ch;
}

unsigned char pg_toupper ( unsigned char  ch  ) 

Definition at line 105 of file pgstrcasecmp.c.

References IS_HIGHBIT_SET.

Referenced by cash_words(), pg_timezone_abbrevs(), pg_tzset(), seq_search(), str_initcap(), and str_toupper().

{
    if (ch >= 'a' && ch <= 'z')
        ch += 'A' - 'a';
    else if (IS_HIGHBIT_SET(ch) && islower(ch))
        ch = toupper(ch);
    return ch;
}

void pg_usleep ( long  microsec  ) 
char** pgfnames ( const char *  path  ) 

Definition at line 363 of file dirmod.c.

References _, closedir(), dirent::d_name, elog, NULL, opendir(), palloc(), pstrdup(), readdir(), repalloc(), strerror(), and WARNING.

Referenced by convert_sourcefiles_in(), rmtree(), and scan_available_timezones().

{
    DIR        *dir;
    struct dirent *file;
    char      **filenames;
    int         numnames = 0;
    int         fnsize = 200;   /* enough for many small dbs */

    dir = opendir(path);
    if (dir == NULL)
    {
#ifndef FRONTEND
        elog(WARNING, "could not open directory \"%s\": %m", path);
#else
        fprintf(stderr, _("could not open directory \"%s\": %s\n"),
                path, strerror(errno));
#endif
        return NULL;
    }

    filenames = (char **) palloc(fnsize * sizeof(char *));

    errno = 0;
    while ((file = readdir(dir)) != NULL)
    {
        if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0)
        {
            if (numnames + 1 >= fnsize)
            {
                fnsize *= 2;
                filenames = (char **) repalloc(filenames,
                                               fnsize * sizeof(char *));
            }
            filenames[numnames++] = pstrdup(file->d_name);
        }
        errno = 0;
    }
#ifdef WIN32

    /*
     * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in
     * released version
     */
    if (GetLastError() == ERROR_NO_MORE_FILES)
        errno = 0;
#endif
    if (errno)
    {
#ifndef FRONTEND
        elog(WARNING, "could not read directory \"%s\": %m", path);
#else
        fprintf(stderr, _("could not read directory \"%s\": %s\n"),
                path, strerror(errno));
#endif
    }

    filenames[numnames] = NULL;

    closedir(dir);

    return filenames;
}

void pgfnames_cleanup ( char **  filenames  ) 

Definition at line 433 of file dirmod.c.

References pfree().

Referenced by convert_sourcefiles_in(), rmtree(), and scan_available_timezones().

{
    char      **fn;

    for (fn = filenames; *fn; fn++)
        pfree(*fn);

    pfree(filenames);
}

int pqGethostbyname ( const char *  name,
struct hostent *  resultbuf,
char *  buffer,
size_t  buflen,
struct hostent **  result,
int *  herrno 
)

Definition at line 122 of file thread.c.

References NULL.

Referenced by getaddrinfo().

{
#if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETHOSTBYNAME_R)

    /*
     * broken (well early POSIX draft) gethostbyname_r() which returns 'struct
     * hostent *'
     */
    *result = gethostbyname_r(name, resultbuf, buffer, buflen, herrno);
    return (*result == NULL) ? -1 : 0;
#else

    /* no gethostbyname_r(), just use gethostbyname() */
    *result = gethostbyname(name);

    if (*result != NULL)
        *herrno = h_errno;

    if (*result != NULL)
        return 0;
    else
        return -1;
#endif
}

int pqGetpwuid ( uid_t  uid,
struct passwd *  resultbuf,
char *  buffer,
size_t  buflen,
struct passwd **  result 
)

Definition at line 89 of file thread.c.

References NULL.

Referenced by get_home_path(), pg_fe_getauthname(), PQconnectPoll(), and pqGetHomeDirectory().

{
#if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_GETPWUID_R)

#ifdef GETPWUID_R_5ARG
    /* POSIX version */
    getpwuid_r(uid, resultbuf, buffer, buflen, result);
#else

    /*
     * Early POSIX draft of getpwuid_r() returns 'struct passwd *'.
     * getpwuid_r(uid, resultbuf, buffer, buflen)
     */
    *result = getpwuid_r(uid, resultbuf, buffer, buflen);
#endif
#else

    /* no getpwuid_r() available, just use getpwuid() */
    *result = getpwuid(uid);
#endif

    return (*result == NULL) ? -1 : 0;
}

pqsigfunc pqsignal ( int  signo,
pqsigfunc  func 
)
char* pqStrerror ( int  errnum,
char *  strerrbuf,
size_t  buflen 
)

Definition at line 61 of file thread.c.

References strerror(), and strlcpy().

Referenced by lo_export(), lo_import_internal(), pg_local_sendauth(), and PQconnectPoll().

{
#if defined(FRONTEND) && defined(ENABLE_THREAD_SAFETY) && defined(HAVE_STRERROR_R)
    /* reentrant strerror_r is available */
#ifdef STRERROR_R_INT
    /* SUSv3 version */
    if (strerror_r(errnum, strerrbuf, buflen) == 0)
        return strerrbuf;
    else
        return "Unknown error";
#else
    /* GNU libc */
    return strerror_r(errnum, strerrbuf, buflen);
#endif
#else
    /* no strerror_r() available, just use strerror */
    strlcpy(strerrbuf, strerror(errnum), buflen);

    return strerrbuf;
#endif
}

void qsort_arg ( void *  base,
size_t  nel,
size_t  elsize,
qsort_arg_comparator  cmp,
void *  arg 
)

Definition at line 103 of file qsort_arg.c.

References cmp(), med3(), Min, qsort_arg(), swap, SWAPINIT, and vecswap.

Referenced by _bt_sort_array_elements(), compute_range_stats(), compute_scalar_stats(), gbt_var_picksplit(), ginExtractEntries(), mcelem_array_selec(), qsort_arg(), range_gist_double_sorting_split(), range_gist_single_sorting_split(), SortAndUniqItems(), spg_range_quad_picksplit(), tsvectorrecv(), and uniqueentry().

{
    char       *pa,
               *pb,
               *pc,
               *pd,
               *pl,
               *pm,
               *pn;
    int         d,
                r,
                swaptype,
                presorted;

loop:SWAPINIT(a, es);
    if (n < 7)
    {
        for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
            for (pl = pm; pl > (char *) a && cmp(pl - es, pl, arg) > 0;
                 pl -= es)
                swap(pl, pl - es);
        return;
    }
    presorted = 1;
    for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
    {
        if (cmp(pm - es, pm, arg) > 0)
        {
            presorted = 0;
            break;
        }
    }
    if (presorted)
        return;
    pm = (char *) a + (n / 2) * es;
    if (n > 7)
    {
        pl = (char *) a;
        pn = (char *) a + (n - 1) * es;
        if (n > 40)
        {
            d = (n / 8) * es;
            pl = med3(pl, pl + d, pl + 2 * d, cmp, arg);
            pm = med3(pm - d, pm, pm + d, cmp, arg);
            pn = med3(pn - 2 * d, pn - d, pn, cmp, arg);
        }
        pm = med3(pl, pm, pn, cmp, arg);
    }
    swap(a, pm);
    pa = pb = (char *) a + es;
    pc = pd = (char *) a + (n - 1) * es;
    for (;;)
    {
        while (pb <= pc && (r = cmp(pb, a, arg)) <= 0)
        {
            if (r == 0)
            {
                swap(pa, pb);
                pa += es;
            }
            pb += es;
        }
        while (pb <= pc && (r = cmp(pc, a, arg)) >= 0)
        {
            if (r == 0)
            {
                swap(pc, pd);
                pd -= es;
            }
            pc -= es;
        }
        if (pb > pc)
            break;
        swap(pb, pc);
        pb += es;
        pc -= es;
    }
    pn = (char *) a + n * es;
    r = Min(pa - (char *) a, pb - pa);
    vecswap(a, pb - r, r);
    r = Min(pd - pc, pn - pd - es);
    vecswap(pb, pn - r, r);
    if ((r = pb - pa) > es)
        qsort_arg(a, r / es, es, cmp, arg);
    if ((r = pd - pc) > es)
    {
        /* Iterate rather than recurse to save stack space */
        a = pn - r;
        n = r / es;
        goto loop;
    }
/*      qsort_arg(pn - r, r / es, es, cmp, arg);*/
}

long random ( void   ) 
double rint ( double  x  ) 
bool rmtree ( const char *  path,
bool  rmtopdir 
)

Definition at line 456 of file dirmod.c.

References _, elog, filename, lstat, MAXPGPATH, NULL, pgfnames(), pgfnames_cleanup(), rmtree(), snprintf(), strerror(), unlink(), and WARNING.

Referenced by convert_sourcefiles_in(), copy_subdir_files(), create_tablespace_directories(), dbase_redo(), exit_nicely(), movedb(), movedb_failure_callback(), regression_main(), remove_dbtablespaces(), and rmtree().

{
    bool        result = true;
    char        pathbuf[MAXPGPATH];
    char      **filenames;
    char      **filename;
    struct stat statbuf;

    /*
     * we copy all the names out of the directory before we start modifying
     * it.
     */
    filenames = pgfnames(path);

    if (filenames == NULL)
        return false;

    /* now we have the names we can start removing things */
    for (filename = filenames; *filename; filename++)
    {
        snprintf(pathbuf, MAXPGPATH, "%s/%s", path, *filename);

        /*
         * It's ok if the file is not there anymore; we were just about to
         * delete it anyway.
         *
         * This is not an academic possibility. One scenario where this
         * happens is when bgwriter has a pending unlink request for a file in
         * a database that's being dropped. In dropdb(), we call
         * ForgetDatabaseFsyncRequests() to flush out any such pending unlink
         * requests, but because that's asynchronous, it's not guaranteed that
         * the bgwriter receives the message in time.
         */
        if (lstat(pathbuf, &statbuf) != 0)
        {
            if (errno != ENOENT)
            {
#ifndef FRONTEND
                elog(WARNING, "could not stat file or directory \"%s\": %m",
                     pathbuf);
#else
                fprintf(stderr, _("could not stat file or directory \"%s\": %s\n"),
                        pathbuf, strerror(errno));
#endif
                result = false;
            }
            continue;
        }

        if (S_ISDIR(statbuf.st_mode))
        {
            /* call ourselves recursively for a directory */
            if (!rmtree(pathbuf, true))
            {
                /* we already reported the error */
                result = false;
            }
        }
        else
        {
            if (unlink(pathbuf) != 0)
            {
                if (errno != ENOENT)
                {
#ifndef FRONTEND
                    elog(WARNING, "could not remove file or directory \"%s\": %m",
                         pathbuf);
#else
                    fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
                            pathbuf, strerror(errno));
#endif
                    result = false;
                }
            }
        }
    }

    if (rmtopdir)
    {
        if (rmdir(path) != 0)
        {
#ifndef FRONTEND
            elog(WARNING, "could not remove file or directory \"%s\": %m",
                 path);
#else
            fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
                    path, strerror(errno));
#endif
            result = false;
        }
    }

    pgfnames_cleanup(filenames);

    return result;
}

void set_pglocale_pgservice ( const char *  argv0,
const char *  app 
)

Definition at line 550 of file exec.c.

References canonicalize_path(), find_my_exec(), get_etc_path(), get_locale_path(), MAXPGPATH, my_exec_path, NULL, PG_TEXTDOMAIN, putenv, and snprintf().

Referenced by main(), and regression_main().

{
    char        path[MAXPGPATH];
    char        my_exec_path[MAXPGPATH];
    char        env_path[MAXPGPATH + sizeof("PGSYSCONFDIR=")];  /* longer than
                                                                 * PGLOCALEDIR */

    /* don't set LC_ALL in the backend */
    if (strcmp(app, PG_TEXTDOMAIN("postgres")) != 0)
        setlocale(LC_ALL, "");

    if (find_my_exec(argv0, my_exec_path) < 0)
        return;

#ifdef ENABLE_NLS
    get_locale_path(my_exec_path, path);
    bindtextdomain(app, path);
    textdomain(app);

    if (getenv("PGLOCALEDIR") == NULL)
    {
        /* set for libpq to use */
        snprintf(env_path, sizeof(env_path), "PGLOCALEDIR=%s", path);
        canonicalize_path(env_path + 12);
        putenv(strdup(env_path));
    }
#endif

    if (getenv("PGSYSCONFDIR") == NULL)
    {
        get_etc_path(my_exec_path, path);

        /* set for libpq to use */
        snprintf(env_path, sizeof(env_path), "PGSYSCONFDIR=%s", path);
        canonicalize_path(env_path + 13);
        putenv(strdup(env_path));
    }
}

char * simple_prompt ( const char *  prompt,
int  maxlen,
bool  echo 
)

Definition at line 38 of file sprompt.c.

References _, buf, free, malloc, and NULL.

Referenced by _connectDB(), ConnectDatabase(), connectDatabase(), doConnect(), exec_command(), get_set_pwd(), GetConnection(), main(), prompt_for_password(), sql_conn(), vacuumlo(), and yesno_prompt().

{
    int         length;
    char       *destination;
    FILE       *termin,
               *termout;

#ifdef HAVE_TERMIOS_H
    struct termios t_orig,
                t;
#else
#ifdef WIN32
    HANDLE      t = NULL;
    LPDWORD     t_orig = NULL;
#endif
#endif

    destination = (char *) malloc(maxlen + 1);
    if (!destination)
        return NULL;

#ifdef WIN32

    /*
     * A Windows console has an "input code page" and an "output code page";
     * these usually match each other, but they rarely match the "Windows ANSI
     * code page" defined at system boot and expected of "char *" arguments to
     * Windows API functions.  The Microsoft CRT write() implementation
     * automatically converts text between these code pages when writing to a
     * console.  To identify such file descriptors, it calls GetConsoleMode()
     * on the underlying HANDLE, which in turn requires GENERIC_READ access on
     * the HANDLE.  Opening termout in mode "w+" allows that detection to
     * succeed.  Otherwise, write() would not recognize the descriptor as a
     * console, and non-ASCII characters would display incorrectly.
     *
     * XXX fgets() still receives text in the console's input code page.  This
     * makes non-ASCII credentials unportable.
     */
    termin = fopen("CONIN$", "r");
    termout = fopen("CONOUT$", "w+");
#else

    /*
     * Do not try to collapse these into one "w+" mode file. Doesn't work on
     * some platforms (eg, HPUX 10.20).
     */
    termin = fopen("/dev/tty", "r");
    termout = fopen("/dev/tty", "w");
#endif
    if (!termin || !termout
#ifdef WIN32
    /*
     * Direct console I/O does not work from the MSYS 1.0.10 console.  Writes
     * reach nowhere user-visible; reads block indefinitely.  XXX This affects
     * most Windows terminal environments, including rxvt, mintty, Cygwin
     * xterm, Cygwin sshd, and PowerShell ISE.  Switch to a more-generic test.
     */
        || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0)
#endif
        )
    {
        if (termin)
            fclose(termin);
        if (termout)
            fclose(termout);
        termin = stdin;
        termout = stderr;
    }

#ifdef HAVE_TERMIOS_H
    if (!echo)
    {
        tcgetattr(fileno(termin), &t);
        t_orig = t;
        t.c_lflag &= ~ECHO;
        tcsetattr(fileno(termin), TCSAFLUSH, &t);
    }
#else
#ifdef WIN32
    if (!echo)
    {
        /* get a new handle to turn echo off */
        t_orig = (LPDWORD) malloc(sizeof(DWORD));
        t = GetStdHandle(STD_INPUT_HANDLE);

        /* save the old configuration first */
        GetConsoleMode(t, t_orig);

        /* set to the new mode */
        SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
    }
#endif
#endif

    if (prompt)
    {
        fputs(_(prompt), termout);
        fflush(termout);
    }

    if (fgets(destination, maxlen + 1, termin) == NULL)
        destination[0] = '\0';

    length = strlen(destination);
    if (length > 0 && destination[length - 1] != '\n')
    {
        /* eat rest of the line */
        char        buf[128];
        int         buflen;

        do
        {
            if (fgets(buf, sizeof(buf), termin) == NULL)
                break;
            buflen = strlen(buf);
        } while (buflen > 0 && buf[buflen - 1] != '\n');
    }

    if (length > 0 && destination[length - 1] == '\n')
        /* remove trailing newline */
        destination[length - 1] = '\0';

#ifdef HAVE_TERMIOS_H
    if (!echo)
    {
        tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
        fputs("\n", termout);
        fflush(termout);
    }
#else
#ifdef WIN32
    if (!echo)
    {
        /* reset to the original console mode */
        SetConsoleMode(t, *t_orig);
        fputs("\n", termout);
        fflush(termout);
        free(t_orig);
    }
#endif
#endif

    if (termin != stdin)
    {
        fclose(termin);
        fclose(termout);
    }

    return destination;
}

void srandom ( unsigned int  seed  ) 

Definition at line 22 of file srandom.c.

References pg_srand48().

Referenced by BackendRun(), main(), PostmasterRandom(), and setseed().

{
    pg_srand48((long int) seed);
}

size_t strlcat ( char *  dst,
const char *  src,
size_t  siz 
)

Definition at line 33 of file strlcat.c.

Referenced by CreateLockFile(), get_prompt(), show_pgxs(), and validate_exec().

{
    char       *d = dst;
    const char *s = src;
    size_t      n = siz;
    size_t      dlen;

    /* Find the end of dst and adjust bytes left but don't go past end */
    while (n-- != 0 && *d != '\0')
        d++;
    dlen = d - dst;
    n = siz - dlen;

    if (n == 0)
        return (dlen + strlen(s));
    while (*s != '\0')
    {
        if (n != 1)
        {
            *d++ = *s;
            n--;
        }
        s++;
    }
    *d = '\0';

    return (dlen + (s - src));  /* count does not include NUL */
}

size_t strlcpy ( char *  dst,
const char *  src,
size_t  siz 
)

Definition at line 45 of file strlcpy.c.

Referenced by AuxiliaryProcessMain(), chkpass_in(), ChooseIndexNameAddition(), connectFailureMessage(), create_rel_filename_map(), create_script_for_old_cluster_deletion(), createNewConnection(), descriptor_variable(), exec_prog(), expand_tilde(), fetch_fp_info(), find_in_dynamic_libpath(), find_other_exec_or_die(), from_char_parse_int_len(), from_char_seq_search(), get_control_data(), get_home_path(), get_prompt(), get_rel_infos(), getPgPassFilename(), hash_create(), InitPostgres(), internal_cancel(), join_path_components(), logfile_getname(), main(), make_oper_cache_key(), make_relative_path(), old_8_3_rebuild_tsvector_tables(), ParseLongOption(), parseServiceInfo(), pg_getnameinfo_all(), pg_open_tzfile(), pg_TZDIR(), pgarch_archiveXlog(), pgstat_bestart(), PQcancel(), pqGetHomeDirectory(), PQrequestCancel(), pqStrerror(), process_file(), process_postgres_switches(), RegisterBackgroundWorker(), replace_string(), RequestXLogStreaming(), scan_available_timezones(), scan_directory_ci(), set_ps_display(), setup_bin_paths(), test_postmaster_connection(), timestamptz_to_str(), and WalReceiverMain().

{
    char       *d = dst;
    const char *s = src;
    size_t      n = siz;

    /* Copy as many bytes as will fit */
    if (n != 0)
    {
        while (--n != 0)
        {
            if ((*d++ = *s++) == '\0')
                break;
        }
    }

    /* Not enough room in dst, add NUL and traverse rest of src */
    if (n == 0)
    {
        if (siz != 0)
            *d = '\0';          /* NUL-terminate dst */
        while (*s++)
            ;
    }

    return (s - src - 1);       /* count does not include NUL */
}

void unsetenv ( const char *  name  ) 

Definition at line 20 of file unsetenv.c.

References malloc, NULL, and putenv.

{
    char       *envstr;

    if (getenv(name) == NULL)
        return;                 /* no work */

    /*
     * The technique embodied here works if libc follows the Single Unix Spec
     * and actually uses the storage passed to putenv() to hold the environ
     * entry.  When we clobber the entry in the second step we are ensuring
     * that we zap the actual environ member.  However, there are some libc
     * implementations (notably recent BSDs) that do not obey SUS but copy the
     * presented string.  This method fails on such platforms.  Hopefully all
     * such platforms have unsetenv() and thus won't be using this hack. See:
     * http://www.greenend.org.uk/rjk/2008/putenv.html
     *
     * Note that repeatedly setting and unsetting a var using this code will
     * leak memory.
     */

    envstr = (char *) malloc(strlen(name) + 2);
    if (!envstr)                /* not much we can do if no memory */
        return;

    /* Override the existing setting by forcibly defining the var */
    sprintf(envstr, "%s=", name);
    putenv(envstr);

    /* Now we can clobber the variable definition this way: */
    strcpy(envstr, "=");

    /*
     * This last putenv cleans up if we have multiple zero-length names as a
     * result of unsetting multiple things.
     */
    putenv(envstr);
}

char* wait_result_to_str ( int  exit_status  ) 

Definition at line 34 of file wait_error.c.

References _, pstrdup(), snprintf(), WEXITSTATUS, WIFEXITED, WIFSIGNALED, and WTERMSIG.

Referenced by ClosePipeToProgram(), do_copy(), and pclose_check().

{
    char        str[512];

    if (WIFEXITED(exitstatus))
    {
        /*
         * Give more specific error message for some common exit codes that
         * have a special meaning in shells.
         */
        switch (WEXITSTATUS(exitstatus))
        {
            case 126:
                snprintf(str, sizeof(str), _("command not executable"));
                break;

            case 127:
                snprintf(str, sizeof(str), _("command not found"));
                break;

            default:
                snprintf(str, sizeof(str),
                         _("child process exited with exit code %d"),
                         WEXITSTATUS(exitstatus));
        }
    }
    else if (WIFSIGNALED(exitstatus))
#if defined(WIN32)
        snprintf(str, sizeof(str),
                 _("child process was terminated by exception 0x%X"),
                 WTERMSIG(exitstatus));
#elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST
    {
        char        str2[256];

        snprintf(str2, sizeof(str2), "%d: %s", WTERMSIG(exitstatus),
                 WTERMSIG(exitstatus) < NSIG ?
                 sys_siglist[WTERMSIG(exitstatus)] : "(unknown)");
        snprintf(str, sizeof(str),
                 _("child process was terminated by signal %s"), str2);
    }
#else
        snprintf(str, sizeof(str),
                 _("child process was terminated by signal %d"),
                 WTERMSIG(exitstatus));
#endif
    else
        snprintf(str, sizeof(str),
                 _("child process exited with unrecognized status %d"),
                  exitstatus);

    return pstrdup(str);
}