Header And Logo

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

Data Structures | Defines | Typedefs | Functions | Variables

win32.h File Reference

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <process.h>
#include <signal.h>
#include <errno.h>
#include <direct.h>
#include <sys/utime.h>
Include dependency graph for win32.h:

Go to the source code of this file.

Data Structures

struct  timezone
struct  itimerval

Defines

#define _WIN32_WINNT   0x0501
#define ENABLE_SSPI   1
#define _WINSOCKAPI_
#define mkdir(a, b)   mkdir(a)
#define ftruncate(a, b)   chsize(a,b)
#define fsync(fd)   _commit(fd)
#define HAVE_FSYNC_WRITETHROUGH
#define FSYNC_WRITETHROUGH_IS_FSYNC
#define USES_WINSOCK
#define PGDLLIMPORT
#define PGDLLEXPORT
#define HAVE_UNION_SEMUN   1
#define IPC_RMID   256
#define IPC_CREAT   512
#define IPC_EXCL   1024
#define IPC_PRIVATE   234564
#define IPC_NOWAIT   2048
#define IPC_STAT   4096
#define EACCESS   2048
#define EIDRM   4096
#define SETALL   8192
#define GETNCNT   16384
#define GETVAL   65536
#define SETVAL   131072
#define GETPID   262144
#define WIFEXITED(w)   (((w) & 0XFFFFFF00) == 0)
#define WIFSIGNALED(w)   (!WIFEXITED(w))
#define WEXITSTATUS(w)   (w)
#define WTERMSIG(w)   (w)
#define sigmask(sig)   ( 1 << ((sig)-1) )
#define SIG_DFL   ((pqsigfunc)0)
#define SIG_ERR   ((pqsigfunc)-1)
#define SIG_IGN   ((pqsigfunc)1)
#define SIGHUP   1
#define SIGQUIT   3
#define SIGTRAP   5
#define SIGABRT   22
#define SIGKILL   9
#define SIGPIPE   13
#define SIGALRM   14
#define SIGSTOP   17
#define SIGTSTP   18
#define SIGCONT   19
#define SIGCHLD   20
#define SIGTTIN   21
#define SIGTTOU   22
#define SIGWINCH   28
#define SIGUSR1   30
#define SIGUSR2   31
#define ITIMER_REAL   0
#define pgoff_t   __int64
#define fseeko(stream, offset, origin)   fseeko64(stream, offset, origin)
#define ftello(stream)   ftello64(stream)
#define lstat(path, sb)   stat((path), (sb))
#define O_DSYNC   0x0080
#define EINTR   WSAEINTR
#define EAGAIN   WSAEWOULDBLOCK
#define EMSGSIZE   WSAEMSGSIZE
#define EAFNOSUPPORT   WSAEAFNOSUPPORT
#define EWOULDBLOCK   WSAEWOULDBLOCK
#define ECONNRESET   WSAECONNRESET
#define EINPROGRESS   WSAEINPROGRESS
#define ENOBUFS   WSAENOBUFS
#define EPROTONOSUPPORT   WSAEPROTONOSUPPORT
#define ECONNREFUSED   WSAECONNREFUSED
#define EBADFD   WSAENOTSOCK
#define EOPNOTSUPP   WSAEOPNOTSUPP
#define locale_t   _locale_t
#define tolower_l   _tolower_l
#define toupper_l   _toupper_l
#define towlower_l   _towlower_l
#define towupper_l   _towupper_l
#define isdigit_l   _isdigit_l
#define iswdigit_l   _iswdigit_l
#define isalpha_l   _isalpha_l
#define iswalpha_l   _iswalpha_l
#define isalnum_l   _isalnum_l
#define iswalnum_l   _iswalnum_l
#define isupper_l   _isupper_l
#define iswupper_l   _iswupper_l
#define islower_l   _islower_l
#define iswlower_l   _iswlower_l
#define isgraph_l   _isgraph_l
#define iswgraph_l   _iswgraph_l
#define isprint_l   _isprint_l
#define iswprint_l   _iswprint_l
#define ispunct_l   _ispunct_l
#define iswpunct_l   _iswpunct_l
#define isspace_l   _isspace_l
#define iswspace_l   _iswspace_l
#define strcoll_l   _strcoll_l
#define wcscoll_l   _wcscoll_l
#define wcstombs_l   _wcstombs_l
#define mbstowcs_l   _mbstowcs_l
#define UNBLOCKED_SIGNAL_QUEUE()   (pg_signal_queue & ~pg_signal_mask)
#define socket(af, type, protocol)   pgwin32_socket(af, type, protocol)
#define accept(s, addr, addrlen)   pgwin32_accept(s, addr, addrlen)
#define connect(s, name, namelen)   pgwin32_connect(s, name, namelen)
#define select(n, r, w, e, timeout)   pgwin32_select(n, r, w, e, timeout)
#define recv(s, buf, len, flags)   pgwin32_recv(s, buf, len, flags)
#define send(s, buf, len, flags)   pgwin32_send(s, buf, len, flags)
#define putenv(x)   pgwin32_putenv(x)
#define unsetenv(x)   pgwin32_unsetenv(x)
#define S_IRGRP   0
#define S_IWGRP   0
#define S_IXGRP   0
#define S_IRWXG   0
#define S_IROTH   0
#define S_IWOTH   0
#define S_IXOTH   0
#define S_IRWXO   0

Typedefs

typedef int uid_t
typedef int gid_t
typedef long key_t

Functions

int setitimer (int which, const struct itimerval *value, struct itimerval *ovalue)
void pgwin32_signal_initialize (void)
HANDLE pgwin32_create_signal_listener (pid_t pid)
void pgwin32_dispatch_queued_signals (void)
void pg_queue_signal (int signum)
SOCKET pgwin32_socket (int af, int type, int protocol)
SOCKET pgwin32_accept (SOCKET s, struct sockaddr *addr, int *addrlen)
int pgwin32_connect (SOCKET s, const struct sockaddr *name, int namelen)
int pgwin32_select (int nfds, fd_set *readfs, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout)
int pgwin32_recv (SOCKET s, char *buf, int len, int flags)
int pgwin32_send (SOCKET s, const void *buf, int len, int flags)
const char * pgwin32_socket_strerror (int err)
int pgwin32_waitforsinglesocket (SOCKET s, int what, int timeout)
int pgwin32_is_admin (void)
int pgwin32_is_service (void)
int pgwin32_ReserveSharedMemoryRegion (HANDLE)
void pgwin32_install_crashdump_handler (void)
void _dosmaperr (unsigned long)
int pgwin32_putenv (const char *)
void pgwin32_unsetenv (const char *)

Variables

PGDLLIMPORT volatile int pg_signal_queue
PGDLLIMPORT int pg_signal_mask
HANDLE pgwin32_signal_event
HANDLE pgwin32_initial_signal_pipe
int pgwin32_noblock

Define Documentation

#define _WIN32_WINNT   0x0501

Definition at line 15 of file win32.h.

#define _WINSOCKAPI_

Definition at line 35 of file win32.h.

#define accept (   s,
  addr,
  addrlen 
)    pgwin32_accept(s, addr, addrlen)

Definition at line 376 of file win32.h.

Referenced by StreamConnection().

#define connect (   s,
  name,
  namelen 
)    pgwin32_connect(s, name, namelen)

Definition at line 377 of file win32.h.

Referenced by ident_inet(), internal_cancel(), pgstat_init(), and PQconnectPoll().

#define EACCESS   2048

Definition at line 107 of file win32.h.

#define EAFNOSUPPORT   WSAEAFNOSUPPORT

Definition at line 279 of file win32.h.

#define EAGAIN   WSAEWOULDBLOCK
#define EBADFD   WSAENOTSOCK

Definition at line 300 of file win32.h.

#define ECONNREFUSED   WSAECONNREFUSED

Definition at line 297 of file win32.h.

#define ECONNRESET   WSAECONNRESET

Definition at line 285 of file win32.h.

Referenced by errcode_for_socket_access(), pqReadData(), pqsecure_read(), and pqsecure_write().

#define EIDRM   4096
#define EINPROGRESS   WSAEINPROGRESS

Definition at line 288 of file win32.h.

Referenced by PQconnectPoll().

#define EINTR   WSAEINTR
#define EMSGSIZE   WSAEMSGSIZE

Definition at line 276 of file win32.h.

#define ENABLE_SSPI   1

Definition at line 22 of file win32.h.

#define ENOBUFS   WSAENOBUFS

Definition at line 291 of file win32.h.

#define EOPNOTSUPP   WSAEOPNOTSUPP

Definition at line 303 of file win32.h.

#define EPROTONOSUPPORT   WSAEPROTONOSUPPORT

Definition at line 294 of file win32.h.

#define EWOULDBLOCK   WSAEWOULDBLOCK
#define fseeko (   stream,
  offset,
  origin 
)    fseeko64(stream, offset, origin)
#define fsync (   fd  )     _commit(fd)
#define FSYNC_WRITETHROUGH_IS_FSYNC

Definition at line 64 of file win32.h.

#define ftello (   stream  )     ftello64(stream)
#define ftruncate (   a,
  b 
)    chsize(a,b)

Definition at line 53 of file win32.h.

Referenced by CheckForExternalTrigger(), FileTruncate(), and mdunlinkfork().

#define GETNCNT   16384

Definition at line 113 of file win32.h.

#define GETPID   262144

Definition at line 116 of file win32.h.

Referenced by IpcSemaphoreGetLastPID().

#define GETVAL   65536

Definition at line 114 of file win32.h.

Referenced by IpcSemaphoreGetValue().

#define HAVE_FSYNC_WRITETHROUGH

Definition at line 63 of file win32.h.

#define HAVE_UNION_SEMUN   1

Definition at line 98 of file win32.h.

#define IPC_CREAT   512

Definition at line 101 of file win32.h.

Referenced by InternalIpcMemoryCreate(), and InternalIpcSemaphoreCreate().

#define IPC_EXCL   1024

Definition at line 102 of file win32.h.

Referenced by InternalIpcMemoryCreate(), and InternalIpcSemaphoreCreate().

#define IPC_NOWAIT   2048

Definition at line 104 of file win32.h.

#define IPC_PRIVATE   234564

Definition at line 103 of file win32.h.

#define IPC_RMID   256
#define IPC_STAT   4096

Definition at line 105 of file win32.h.

Referenced by PGSharedMemoryIsInUse().

#define isalnum_l   _isalnum_l

Definition at line 339 of file win32.h.

Referenced by pg_wc_isalnum(), and str_initcap().

#define isalpha_l   _isalpha_l

Definition at line 337 of file win32.h.

Referenced by pattern_char_isalpha(), and pg_wc_isalpha().

#define isdigit_l   _isdigit_l

Definition at line 335 of file win32.h.

Referenced by pg_wc_isdigit().

#define isgraph_l   _isgraph_l

Definition at line 345 of file win32.h.

Referenced by pg_wc_isgraph().

#define islower_l   _islower_l

Definition at line 343 of file win32.h.

Referenced by pg_wc_islower().

#define isprint_l   _isprint_l

Definition at line 347 of file win32.h.

Referenced by pg_wc_isprint().

#define ispunct_l   _ispunct_l

Definition at line 349 of file win32.h.

Referenced by pg_wc_ispunct().

#define isspace_l   _isspace_l

Definition at line 351 of file win32.h.

Referenced by pg_wc_isspace().

#define isupper_l   _isupper_l

Definition at line 341 of file win32.h.

Referenced by pg_wc_isupper().

#define iswalnum_l   _iswalnum_l

Definition at line 340 of file win32.h.

Referenced by pg_wc_isalnum(), and str_initcap().

#define iswalpha_l   _iswalpha_l

Definition at line 338 of file win32.h.

Referenced by pg_wc_isalpha().

#define iswdigit_l   _iswdigit_l

Definition at line 336 of file win32.h.

Referenced by pg_wc_isdigit().

#define iswgraph_l   _iswgraph_l

Definition at line 346 of file win32.h.

Referenced by pg_wc_isgraph().

#define iswlower_l   _iswlower_l

Definition at line 344 of file win32.h.

Referenced by pg_wc_islower().

#define iswprint_l   _iswprint_l

Definition at line 348 of file win32.h.

Referenced by pg_wc_isprint().

#define iswpunct_l   _iswpunct_l

Definition at line 350 of file win32.h.

Referenced by pg_wc_ispunct().

#define iswspace_l   _iswspace_l

Definition at line 352 of file win32.h.

Referenced by pg_wc_isspace().

#define iswupper_l   _iswupper_l

Definition at line 342 of file win32.h.

Referenced by pg_wc_isupper().

#define ITIMER_REAL   0

Definition at line 214 of file win32.h.

Referenced by disable_all_timeouts(), schedule_alarm(), and setitimer().

#define locale_t   _locale_t

Definition at line 330 of file win32.h.

Referenced by pg_newlocale_from_collation().

#define lstat (   path,
  sb 
)    stat((path), (sb))
#define mbstowcs_l   _mbstowcs_l

Definition at line 356 of file win32.h.

#define mkdir (   a,
  b 
)    mkdir(a)
#define O_DSYNC   0x0080

Definition at line 266 of file win32.h.

Referenced by test_sync().

#define PGDLLEXPORT

Definition at line 90 of file win32.h.

#define PGDLLIMPORT

Definition at line 89 of file win32.h.

#define pgoff_t   __int64
#define putenv (   x  )     pgwin32_putenv(x)
#define recv (   s,
  buf,
  len,
  flags 
)    pgwin32_recv(s, buf, len, flags)
#define S_IRGRP   0

Definition at line 466 of file win32.h.

Referenced by lo_export(), and PostmasterMain().

#define S_IROTH   0

Definition at line 470 of file win32.h.

Referenced by lo_export(), and PostmasterMain().

#define S_IRWXG   0
#define S_IRWXO   0
#define S_IWGRP   0

Definition at line 467 of file win32.h.

Referenced by BeginCopyTo(), lo_export(), and main().

#define S_IWOTH   0

Definition at line 471 of file win32.h.

Referenced by BeginCopyTo(), lo_export(), and main().

#define S_IXGRP   0

Definition at line 468 of file win32.h.

#define S_IXOTH   0

Definition at line 472 of file win32.h.

#define select (   n,
  r,
  w,
  e,
  timeout 
)    pgwin32_select(n, r, w, e, timeout)
#define send (   s,
  buf,
  len,
  flags 
)    pgwin32_send(s, buf, len, flags)
#define SETALL   8192

Definition at line 112 of file win32.h.

#define SETVAL   131072

Definition at line 115 of file win32.h.

Referenced by IpcSemaphoreInitialize().

#define SIG_DFL   ((pqsigfunc)0)
#define SIG_ERR   ((pqsigfunc)-1)

Definition at line 178 of file win32.h.

Referenced by pgwin32_dispatch_queued_signals().

#define SIG_IGN   ((pqsigfunc)1)
#define SIGABRT   22

Definition at line 185 of file win32.h.

Referenced by pqinitmask().

#define SIGALRM   14
#define SIGCHLD   20
#define SIGCONT   19
#define SIGHUP   1
#define SIGKILL   9

Definition at line 186 of file win32.h.

Referenced by regression_main().

#define sigmask (   sig  )     ( 1 << ((sig)-1) )

Definition at line 171 of file win32.h.

Referenced by pg_queue_signal(), pgwin32_dispatch_queued_signals(), and pqinitmask().

#define SIGPIPE   13
#define SIGQUIT   3
#define SIGSTOP   17

Definition at line 189 of file win32.h.

Referenced by HandleChildCrash(), and signal_child().

#define SIGTRAP   5

Definition at line 184 of file win32.h.

Referenced by pqinitmask().

#define SIGTSTP   18

Definition at line 190 of file win32.h.

#define SIGTTIN   21
#define SIGTTOU   22
#define SIGUSR1   30
#define SIGUSR2   31
#define SIGWINCH   28
#define socket (   af,
  type,
  protocol 
)    pgwin32_socket(af, type, protocol)
#define strcoll_l   _strcoll_l

Definition at line 353 of file win32.h.

Referenced by varstr_cmp().

#define tolower_l   _tolower_l

Definition at line 331 of file win32.h.

Referenced by pg_wc_tolower(), SB_lower_char(), str_initcap(), and str_tolower().

#define toupper_l   _toupper_l

Definition at line 332 of file win32.h.

Referenced by pg_wc_toupper(), str_initcap(), and str_toupper().

#define towlower_l   _towlower_l

Definition at line 333 of file win32.h.

Referenced by pg_wc_tolower(), str_initcap(), and str_tolower().

#define towupper_l   _towupper_l

Definition at line 334 of file win32.h.

Referenced by pg_wc_toupper(), str_initcap(), and str_toupper().

#define UNBLOCKED_SIGNAL_QUEUE (  )     (pg_signal_queue & ~pg_signal_mask)

Definition at line 365 of file win32.h.

Referenced by pgwin32_dispatch_queued_signals(), and pgwin32_poll_signals().

#define unsetenv (   x  )     pgwin32_unsetenv(x)

Definition at line 413 of file win32.h.

Referenced by bootstrap_template1(), exec_command(), initialize_environment(), main(), and pg_putenv().

#define USES_WINSOCK

Definition at line 66 of file win32.h.

#define wcscoll_l   _wcscoll_l

Definition at line 354 of file win32.h.

Referenced by varstr_cmp().

#define wcstombs_l   _wcstombs_l

Definition at line 355 of file win32.h.

#define WEXITSTATUS (   w  )     (w)
#define WIFEXITED (   w  )     (((w) & 0XFFFFFF00) == 0)
#define WIFSIGNALED (   w  )     (!WIFEXITED(w))
#define WTERMSIG (   w  )     (w)

Typedef Documentation

typedef int gid_t

Definition at line 247 of file win32.h.

typedef long key_t

Definition at line 249 of file win32.h.

typedef int uid_t

Definition at line 246 of file win32.h.


Function Documentation

void _dosmaperr ( unsigned  long  ) 

Definition at line 168 of file win32error.c.

References _, DEBUG5, doserrors, ereport, errmsg_internal(), i, lengthof, LOG, and winerr.

Referenced by BaseBackup(), FileRead(), FileWrite(), getErrorText(), getrusage(), and readdir().

{
    int         i;

    if (e == 0)
    {
        errno = 0;
        return;
    }

    for (i = 0; i < lengthof(doserrors); i++)
    {
        if (doserrors[i].winerr == e)
        {
            errno = doserrors[i].doserr;
#ifndef FRONTEND
            ereport(DEBUG5,
                    (errmsg_internal("mapped win32 error code %lu to %d",
                                     e, errno)));
#elif FRONTEND_DEBUG
            fprintf(stderr, _("mapped win32 error code %lu to %d"), e, errno);
#endif
            return;
        }
    }

#ifndef FRONTEND
    ereport(LOG,
            (errmsg_internal("unrecognized win32 error code: %lu",
                             e)));
#else
    fprintf(stderr, _("unrecognized win32 error code: %lu"), e);
#endif

    errno = EINVAL;
    return;
}

void pg_queue_signal ( int  signum  ) 

Definition at line 209 of file signal.c.

References pg_signal_crit_sec, pg_signal_queue, pgwin32_signal_event, and sigmask.

Referenced by pg_console_handler(), pg_signal_dispatch_thread(), and pg_timer_thread().

{
    if (signum >= PG_SIGNAL_COUNT || signum <= 0)
        return;

    EnterCriticalSection(&pg_signal_crit_sec);
    pg_signal_queue |= sigmask(signum);
    LeaveCriticalSection(&pg_signal_crit_sec);

    SetEvent(pgwin32_signal_event);
}

SOCKET pgwin32_accept ( SOCKET  s,
struct sockaddr *  addr,
int *  addrlen 
)

Definition at line 266 of file socket.c.

References NULL, pgwin32_poll_signals(), and TranslateSocketError().

{
    SOCKET      rs;

    /*
     * Poll for signals, but don't return with EINTR, since we don't handle
     * that in pqcomm.c
     */
    pgwin32_poll_signals();

    rs = WSAAccept(s, addr, addrlen, NULL, 0);
    if (rs == INVALID_SOCKET)
    {
        TranslateSocketError();
        return INVALID_SOCKET;
    }
    return rs;
}

int pgwin32_connect ( SOCKET  s,
const struct sockaddr *  name,
int  namelen 
)

Definition at line 288 of file socket.c.

References NULL, pgwin32_waitforsinglesocket(), and TranslateSocketError().

{
    int         r;

    r = WSAConnect(s, addr, addrlen, NULL, NULL, NULL, NULL);
    if (r == 0)
        return 0;

    if (WSAGetLastError() != WSAEWOULDBLOCK)
    {
        TranslateSocketError();
        return -1;
    }

    while (pgwin32_waitforsinglesocket(s, FD_CONNECT, INFINITE) == 0)
    {
        /* Loop endlessly as long as we are just delivering signals */
    }

    return 0;
}

HANDLE pgwin32_create_signal_listener ( pid_t  pid  ) 

Definition at line 180 of file signal.c.

References ereport, errmsg(), ERROR, NULL, and snprintf().

{
    char        pipename[128];
    HANDLE      pipe;

    snprintf(pipename, sizeof(pipename), "\\\\.\\pipe\\pgsignal_%u", (int) pid);

    pipe = CreateNamedPipe(pipename, PIPE_ACCESS_DUPLEX,
                       PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
                           PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);

    if (pipe == INVALID_HANDLE_VALUE)
        ereport(ERROR,
                (errmsg("could not create signal listener pipe for PID %d: error code %lu",
                        (int) pid, GetLastError())));

    return pipe;
}

void pgwin32_dispatch_queued_signals ( void   ) 

Definition at line 106 of file signal.c.

References i, pg_signal_array, pg_signal_crit_sec, pg_signal_defaults, pg_signal_queue, pgwin32_signal_event, sig, SIG_DFL, SIG_ERR, SIG_IGN, sigmask, and UNBLOCKED_SIGNAL_QUEUE.

Referenced by pg_usleep(), PGSemaphoreLock(), pgwin32_poll_signals(), pgwin32_select(), pgwin32_waitforsinglesocket(), pqsigsetmask(), and WaitLatchOrSocket().

{
    int         i;

    EnterCriticalSection(&pg_signal_crit_sec);
    while (UNBLOCKED_SIGNAL_QUEUE())
    {
        /* One or more unblocked signals queued for execution */
        int         exec_mask = UNBLOCKED_SIGNAL_QUEUE();

        for (i = 0; i < PG_SIGNAL_COUNT; i++)
        {
            if (exec_mask & sigmask(i))
            {
                /* Execute this signal */
                pqsigfunc   sig = pg_signal_array[i];

                if (sig == SIG_DFL)
                    sig = pg_signal_defaults[i];
                pg_signal_queue &= ~sigmask(i);
                if (sig != SIG_ERR && sig != SIG_IGN && sig != SIG_DFL)
                {
                    LeaveCriticalSection(&pg_signal_crit_sec);
                    sig(i);
                    EnterCriticalSection(&pg_signal_crit_sec);
                    break;      /* Restart outer loop, in case signal mask or
                                 * queue has been modified inside signal
                                 * handler */
                }
            }
        }
    }
    ResetEvent(pgwin32_signal_event);
    LeaveCriticalSection(&pg_signal_crit_sec);
}

void pgwin32_install_crashdump_handler ( void   ) 

Definition at line 167 of file crashdump.c.

References crashDumpHandler().

Referenced by main().

{
    SetUnhandledExceptionFilter(crashDumpHandler);
}

int pgwin32_is_admin ( void   ) 

Definition at line 29 of file security.c.

References BOOL(), free, pgwin32_get_dynamic_tokeninfo(), and write_stderr.

Referenced by check_root().

{
    HANDLE      AccessToken;
    char       *InfoBuffer = NULL;
    char        errbuf[256];
    PTOKEN_GROUPS Groups;
    PSID        AdministratorsSid;
    PSID        PowerUsersSid;
    SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
    UINT        x;
    BOOL        success;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &AccessToken))
    {
        write_stderr("could not open process token: error code %lu\n",
                     GetLastError());
        exit(1);
    }

    if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenGroups,
                                       &InfoBuffer, errbuf, sizeof(errbuf)))
    {
        write_stderr("%s", errbuf);
        exit(1);
    }

    Groups = (PTOKEN_GROUPS) InfoBuffer;

    CloseHandle(AccessToken);

    if (!AllocateAndInitializeSid(&NtAuthority, 2,
         SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0,
                                  0, &AdministratorsSid))
    {
        write_stderr("could not get SID for Administrators group: error code %lu\n",
                     GetLastError());
        exit(1);
    }

    if (!AllocateAndInitializeSid(&NtAuthority, 2,
    SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS, 0, 0, 0, 0, 0,
                                  0, &PowerUsersSid))
    {
        write_stderr("could not get SID for PowerUsers group: error code %lu\n",
                     GetLastError());
        exit(1);
    }

    success = FALSE;

    for (x = 0; x < Groups->GroupCount; x++)
    {
        if ((EqualSid(AdministratorsSid, Groups->Groups[x].Sid) && (Groups->Groups[x].Attributes & SE_GROUP_ENABLED)) ||
            (EqualSid(PowerUsersSid, Groups->Groups[x].Sid) && (Groups->Groups[x].Attributes & SE_GROUP_ENABLED)))
        {
            success = TRUE;
            break;
        }
    }

    free(InfoBuffer);
    FreeSid(AdministratorsSid);
    FreeSid(PowerUsersSid);
    return success;
}

int pgwin32_is_service ( void   ) 

Definition at line 113 of file security.c.

References free, and pgwin32_get_dynamic_tokeninfo().

Referenced by send_message_to_server_log(), and write_stderr().

{
    static int  _is_service = -1;
    HANDLE      AccessToken;
    char       *InfoBuffer = NULL;
    char        errbuf[256];
    PTOKEN_GROUPS Groups;
    PTOKEN_USER User;
    PSID        ServiceSid;
    PSID        LocalSystemSid;
    SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
    UINT        x;

    /* Only check the first time */
    if (_is_service != -1)
        return _is_service;

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &AccessToken))
    {
        fprintf(stderr, "could not open process token: error code %lu\n",
                GetLastError());
        return -1;
    }

    /* First check for local system */
    if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenUser, &InfoBuffer,
                                       errbuf, sizeof(errbuf)))
    {
        fprintf(stderr, "%s", errbuf);
        return -1;
    }

    User = (PTOKEN_USER) InfoBuffer;

    if (!AllocateAndInitializeSid(&NtAuthority, 1,
                              SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0,
                                  &LocalSystemSid))
    {
        fprintf(stderr, "could not get SID for local system account\n");
        CloseHandle(AccessToken);
        return -1;
    }

    if (EqualSid(LocalSystemSid, User->User.Sid))
    {
        FreeSid(LocalSystemSid);
        free(InfoBuffer);
        CloseHandle(AccessToken);
        _is_service = 1;
        return _is_service;
    }

    FreeSid(LocalSystemSid);
    free(InfoBuffer);

    /* Now check for group SID */
    if (!pgwin32_get_dynamic_tokeninfo(AccessToken, TokenGroups, &InfoBuffer,
                                       errbuf, sizeof(errbuf)))
    {
        fprintf(stderr, "%s", errbuf);
        return -1;
    }

    Groups = (PTOKEN_GROUPS) InfoBuffer;

    if (!AllocateAndInitializeSid(&NtAuthority, 1,
                                  SECURITY_SERVICE_RID, 0, 0, 0, 0, 0, 0, 0,
                                  &ServiceSid))
    {
        fprintf(stderr, "could not get SID for service group\n");
        free(InfoBuffer);
        CloseHandle(AccessToken);
        return -1;
    }

    _is_service = 0;
    for (x = 0; x < Groups->GroupCount; x++)
    {
        if (EqualSid(ServiceSid, Groups->Groups[x].Sid))
        {
            _is_service = 1;
            break;
        }
    }

    free(InfoBuffer);
    FreeSid(ServiceSid);

    CloseHandle(AccessToken);

    return _is_service;
}

int pgwin32_putenv ( const char *   ) 

Definition at line 21 of file win32env.c.

References free, i, modulename, and NULL.

Referenced by pgwin32_unsetenv().

{
    char       *envcpy;
    char       *cp;

    /*
     * Each version of MSVCRT has its own _putenv() call in the runtime
     * library.
     *
     * mingw always uses MSVCRT.DLL, but if we are in a Visual C++
     * environment, attempt to update the environment in all MSVCRT modules
     * that are currently loaded, to work properly with any third party
     * libraries linked against a different MSVCRT but still relying on
     * environment variables.
     *
     * Also separately update the system environment that gets inherited by
     * subprocesses.
     */
#ifdef _MSC_VER
    typedef int (_cdecl * PUTENVPROC) (const char *);
    static struct
    {
        char       *modulename;
        HMODULE     hmodule;
        PUTENVPROC  putenvFunc;
    }           rtmodules[] =
    {
        {
            "msvcrt", 0, NULL
        },                      /* Visual Studio 6.0 / mingw */
        {
            "msvcr70", 0, NULL
        },                      /* Visual Studio 2002 */
        {
            "msvcr71", 0, NULL
        },                      /* Visual Studio 2003 */
        {
            "msvcr80", 0, NULL
        },                      /* Visual Studio 2005 */
        {
            "msvcr90", 0, NULL
        },                      /* Visual Studio 2008 */
        {
            "msvcr100", 0, NULL
        },                      /* Visual Studio 2010 */
        {
            "msvcr110", 0, NULL
        },                      /* Visual Studio 2012 */
        {
            NULL, 0, NULL
        }
    };
    int         i;

    for (i = 0; rtmodules[i].modulename; i++)
    {
        if (rtmodules[i].putenvFunc == NULL)
        {
            if (rtmodules[i].hmodule == 0)
            {
                /* Not attempted before, so try to find this DLL */
                rtmodules[i].hmodule = GetModuleHandle(rtmodules[i].modulename);
                if (rtmodules[i].hmodule == NULL)
                {
                    /*
                     * Set to INVALID_HANDLE_VALUE so we know we have tried
                     * this one before, and won't try again.
                     */
                    rtmodules[i].hmodule = INVALID_HANDLE_VALUE;
                    continue;
                }
                else
                {
                    rtmodules[i].putenvFunc = (PUTENVPROC) GetProcAddress(rtmodules[i].hmodule, "_putenv");
                    if (rtmodules[i].putenvFunc == NULL)
                    {
                        CloseHandle(rtmodules[i].hmodule);
                        rtmodules[i].hmodule = INVALID_HANDLE_VALUE;
                        continue;
                    }
                }
            }
            else
            {
                /*
                 * Module loaded, but we did not find the function last time.
                 * We're not going to find it this time either...
                 */
                continue;
            }
        }
        /* At this point, putenvFunc is set or we have exited the loop */
        rtmodules[i].putenvFunc(envval);
    }
#endif   /* _MSC_VER */

    /*
     * Update the process environment - to make modifications visible to child
     * processes.
     *
     * Need a copy of the string so we can modify it.
     */
    envcpy = strdup(envval);
    if (!envcpy)
        return -1;
    cp = strchr(envcpy, '=');
    if (cp == NULL)
    {
        free(envcpy);
        return -1;
    }
    *cp = '\0';
    cp++;
    if (strlen(cp))
    {
        /*
         * Only call SetEnvironmentVariable() when we are adding a variable,
         * not when removing it. Calling it on both crashes on at least
         * certain versions of MingW.
         */
        if (!SetEnvironmentVariable(envcpy, cp))
        {
            free(envcpy);
            return -1;
        }
    }
    free(envcpy);

    /* Finally, update our "own" cache */
    return _putenv(envval);
}

int pgwin32_recv ( SOCKET  s,
char *  buf,
int  len,
int  flags 
)

Definition at line 311 of file socket.c.

References ereport, errmsg_internal(), NOTICE, NULL, pg_usleep(), pgwin32_noblock, pgwin32_poll_signals(), pgwin32_waitforsinglesocket(), and TranslateSocketError().

{
    WSABUF      wbuf;
    int         r;
    DWORD       b;
    DWORD       flags = f;
    int         n;

    if (pgwin32_poll_signals())
        return -1;

    wbuf.len = len;
    wbuf.buf = buf;

    r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
    if (r != SOCKET_ERROR && b > 0)
        /* Read succeeded right away */
        return b;

    if (r == SOCKET_ERROR &&
        WSAGetLastError() != WSAEWOULDBLOCK)
    {
        TranslateSocketError();
        return -1;
    }

    if (pgwin32_noblock)
    {
        /*
         * No data received, and we are in "emulated non-blocking mode", so
         * return indicating that we'd block if we were to continue.
         */
        errno = EWOULDBLOCK;
        return -1;
    }

    /* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */

    for (n = 0; n < 5; n++)
    {
        if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT,
                                        INFINITE) == 0)
            return -1;          /* errno already set */

        r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
        if (r == SOCKET_ERROR)
        {
            if (WSAGetLastError() == WSAEWOULDBLOCK)
            {
                /*
                 * There seem to be cases on win2k (at least) where WSARecv
                 * can return WSAEWOULDBLOCK even when
                 * pgwin32_waitforsinglesocket claims the socket is readable.
                 * In this case, just sleep for a moment and try again. We try
                 * up to 5 times - if it fails more than that it's not likely
                 * to ever come back.
                 */
                pg_usleep(10000);
                continue;
            }
            TranslateSocketError();
            return -1;
        }
        return b;
    }
    ereport(NOTICE,
      (errmsg_internal("could not read from ready socket (after retries)")));
    errno = EWOULDBLOCK;
    return -1;
}

int pgwin32_ReserveSharedMemoryRegion ( HANDLE   ) 

Definition at line 342 of file win32_shmem.c.

References Assert, elog, LOG, NULL, UsedShmemSegAddr, and UsedShmemSegSize.

{
    void       *address;

    Assert(UsedShmemSegAddr != NULL);
    Assert(UsedShmemSegSize != 0);

    address = VirtualAllocEx(hChild, UsedShmemSegAddr, UsedShmemSegSize,
                             MEM_RESERVE, PAGE_READWRITE);
    if (address == NULL)
    {
        /* Don't use FATAL since we're running in the postmaster */
        elog(LOG, "could not reserve shared memory region (addr=%p) for child %p: error code %lu",
             UsedShmemSegAddr, hChild, GetLastError());
        return false;
    }
    if (address != UsedShmemSegAddr)
    {
        /*
         * Should never happen - in theory if allocation granularity causes
         * strange effects it could, so check just in case.
         *
         * Don't use FATAL since we're running in the postmaster.
         */
        elog(LOG, "reserved shared memory region got incorrect address %p, expected %p",
             address, UsedShmemSegAddr);
        VirtualFreeEx(hChild, address, 0, MEM_RELEASE);
        return false;
    }

    return true;
}

int pgwin32_select ( int  nfds,
fd_set *  readfs,
fd_set *  writefds,
fd_set *  exceptfds,
const struct timeval *  timeout 
)

Definition at line 451 of file socket.c.

References Assert, buf, elog, ERROR, FALSE, i, NULL, pgwin32_dispatch_queued_signals(), pgwin32_poll_signals(), pgwin32_signal_event, TranslateSocketError(), and TRUE.

{
    WSAEVENT    events[FD_SETSIZE * 2]; /* worst case is readfds totally
                                         * different from writefds, so
                                         * 2*FD_SETSIZE sockets */
    SOCKET      sockets[FD_SETSIZE * 2];
    int         numevents = 0;
    int         i;
    int         r;
    DWORD       timeoutval = WSA_INFINITE;
    FD_SET      outreadfds;
    FD_SET      outwritefds;
    int         nummatches = 0;

    Assert(exceptfds == NULL);

    if (pgwin32_poll_signals())
        return -1;

    FD_ZERO(&outreadfds);
    FD_ZERO(&outwritefds);

    /*
     * Write FDs are different in the way that it is only flagged by
     * WSASelectEvent() if we have tried to write to them first. So try an
     * empty write
     */
    if (writefds)
    {
        for (i = 0; i < writefds->fd_count; i++)
        {
            char        c;
            WSABUF      buf;
            DWORD       sent;

            buf.buf = &c;
            buf.len = 0;

            r = WSASend(writefds->fd_array[i], &buf, 1, &sent, 0, NULL, NULL);
            if (r == 0)         /* Completed - means things are fine! */
                FD_SET(writefds->fd_array[i], &outwritefds);

            else
            {                   /* Not completed */
                if (WSAGetLastError() != WSAEWOULDBLOCK)

                    /*
                     * Not completed, and not just "would block", so an error
                     * occurred
                     */
                    FD_SET(writefds->fd_array[i], &outwritefds);
            }
        }
        if (outwritefds.fd_count > 0)
        {
            memcpy(writefds, &outwritefds, sizeof(fd_set));
            if (readfds)
                FD_ZERO(readfds);
            return outwritefds.fd_count;
        }
    }


    /* Now set up for an actual select */

    if (timeout != NULL)
    {
        /* timeoutval is in milliseconds */
        timeoutval = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
    }

    if (readfds != NULL)
    {
        for (i = 0; i < readfds->fd_count; i++)
        {
            events[numevents] = WSACreateEvent();
            sockets[numevents] = readfds->fd_array[i];
            numevents++;
        }
    }
    if (writefds != NULL)
    {
        for (i = 0; i < writefds->fd_count; i++)
        {
            if (!readfds ||
                !FD_ISSET(writefds->fd_array[i], readfds))
            {
                /* If the socket is not in the read list */
                events[numevents] = WSACreateEvent();
                sockets[numevents] = writefds->fd_array[i];
                numevents++;
            }
        }
    }

    for (i = 0; i < numevents; i++)
    {
        int         flags = 0;

        if (readfds && FD_ISSET(sockets[i], readfds))
            flags |= FD_READ | FD_ACCEPT | FD_CLOSE;

        if (writefds && FD_ISSET(sockets[i], writefds))
            flags |= FD_WRITE | FD_CLOSE;

        if (WSAEventSelect(sockets[i], events[i], flags) != 0)
        {
            TranslateSocketError();
            /* release already-assigned event objects */
            while (--i >= 0)
                WSAEventSelect(sockets[i], NULL, 0);
            for (i = 0; i < numevents; i++)
                WSACloseEvent(events[i]);
            return -1;
        }
    }

    events[numevents] = pgwin32_signal_event;
    r = WaitForMultipleObjectsEx(numevents + 1, events, FALSE, timeoutval, TRUE);
    if (r != WAIT_TIMEOUT && r != WAIT_IO_COMPLETION && r != (WAIT_OBJECT_0 + numevents))
    {
        /*
         * We scan all events, even those not signalled, in case more than one
         * event has been tagged but Wait.. can only return one.
         */
        WSANETWORKEVENTS resEvents;

        for (i = 0; i < numevents; i++)
        {
            ZeroMemory(&resEvents, sizeof(resEvents));
            if (WSAEnumNetworkEvents(sockets[i], events[i], &resEvents) != 0)
                elog(ERROR, "failed to enumerate network events: error code %u",
                     WSAGetLastError());
            /* Read activity? */
            if (readfds && FD_ISSET(sockets[i], readfds))
            {
                if ((resEvents.lNetworkEvents & FD_READ) ||
                    (resEvents.lNetworkEvents & FD_ACCEPT) ||
                    (resEvents.lNetworkEvents & FD_CLOSE))
                {
                    FD_SET(sockets[i], &outreadfds);

                    nummatches++;
                }
            }
            /* Write activity? */
            if (writefds && FD_ISSET(sockets[i], writefds))
            {
                if ((resEvents.lNetworkEvents & FD_WRITE) ||
                    (resEvents.lNetworkEvents & FD_CLOSE))
                {
                    FD_SET(sockets[i], &outwritefds);

                    nummatches++;
                }
            }
        }
    }

    /* Clean up all the event objects */
    for (i = 0; i < numevents; i++)
    {
        WSAEventSelect(sockets[i], NULL, 0);
        WSACloseEvent(events[i]);
    }

    if (r == WSA_WAIT_TIMEOUT)
    {
        if (readfds)
            FD_ZERO(readfds);
        if (writefds)
            FD_ZERO(writefds);
        return 0;
    }

    if (r == WAIT_OBJECT_0 + numevents)
    {
        pgwin32_dispatch_queued_signals();
        errno = EINTR;
        if (readfds)
            FD_ZERO(readfds);
        if (writefds)
            FD_ZERO(writefds);
        return -1;
    }

    /* Overwrite socket sets with our resulting values */
    if (readfds)
        memcpy(readfds, &outreadfds, sizeof(fd_set));
    if (writefds)
        memcpy(writefds, &outwritefds, sizeof(fd_set));
    return nummatches;
}

int pgwin32_send ( SOCKET  s,
const void *  buf,
int  len,
int  flags 
)

Definition at line 393 of file socket.c.

References NULL, pgwin32_noblock, pgwin32_poll_signals(), pgwin32_waitforsinglesocket(), and TranslateSocketError().

{
    WSABUF      wbuf;
    int         r;
    DWORD       b;

    if (pgwin32_poll_signals())
        return -1;

    wbuf.len = len;
    wbuf.buf = (char *) buf;

    /*
     * Readiness of socket to send data to UDP socket may be not true: socket
     * can become busy again! So loop until send or error occurs.
     */
    for (;;)
    {
        r = WSASend(s, &wbuf, 1, &b, flags, NULL, NULL);
        if (r != SOCKET_ERROR && b > 0)
            /* Write succeeded right away */
            return b;

        if (r == SOCKET_ERROR &&
            WSAGetLastError() != WSAEWOULDBLOCK)
        {
            TranslateSocketError();
            return -1;
        }

        if (pgwin32_noblock)
        {
            /*
             * No data sent, and we are in "emulated non-blocking mode", so
             * return indicating that we'd block if we were to continue.
             */
            errno = EWOULDBLOCK;
            return -1;
        }

        /* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */

        if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE, INFINITE) == 0)
            return -1;
    }

    return -1;
}

void pgwin32_signal_initialize ( void   ) 

Definition at line 67 of file signal.c.

References ereport, errmsg_internal(), FALSE, FATAL, i, NULL, pg_console_handler(), pg_signal_array, pg_signal_crit_sec, pg_signal_defaults, pg_signal_mask, pg_signal_queue, pg_signal_thread(), pgwin32_signal_event, and TRUE.

Referenced by main().

{
    int         i;
    HANDLE      signal_thread_handle;

    InitializeCriticalSection(&pg_signal_crit_sec);

    for (i = 0; i < PG_SIGNAL_COUNT; i++)
    {
        pg_signal_array[i] = SIG_DFL;
        pg_signal_defaults[i] = SIG_IGN;
    }
    pg_signal_mask = 0;
    pg_signal_queue = 0;

    /* Create the global event handle used to flag signals */
    pgwin32_signal_event = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (pgwin32_signal_event == NULL)
        ereport(FATAL,
                (errmsg_internal("could not create signal event: error code %lu", GetLastError())));

    /* Create thread for handling signals */
    signal_thread_handle = CreateThread(NULL, 0, pg_signal_thread, NULL, 0, NULL);
    if (signal_thread_handle == NULL)
        ereport(FATAL,
                (errmsg_internal("could not create signal handler thread")));

    /* Create console control handle to pick up Ctrl-C etc */
    if (!SetConsoleCtrlHandler(pg_console_handler, TRUE))
        ereport(FATAL,
                (errmsg_internal("could not set console control handler")));
}

SOCKET pgwin32_socket ( int  af,
int  type,
int  protocol 
)

Definition at line 242 of file socket.c.

References NULL, and TranslateSocketError().

{
    SOCKET      s;
    unsigned long on = 1;

    s = WSASocket(af, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (s == INVALID_SOCKET)
    {
        TranslateSocketError();
        return INVALID_SOCKET;
    }

    if (ioctlsocket(s, FIONBIO, &on))
    {
        TranslateSocketError();
        return INVALID_SOCKET;
    }
    errno = 0;

    return s;
}

const char* pgwin32_socket_strerror ( int  err  ) 

Definition at line 652 of file socket.c.

References ereport, errmsg_internal(), FATAL, NULL, and wserrbuf.

Referenced by useful_strerror().

{
    static HANDLE handleDLL = INVALID_HANDLE_VALUE;

    if (handleDLL == INVALID_HANDLE_VALUE)
    {
        handleDLL = LoadLibraryEx("netmsg.dll", NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
        if (handleDLL == NULL)
            ereport(FATAL,
                    (errmsg_internal("could not load netmsg.dll: error code %lu", GetLastError())));
    }

    ZeroMemory(&wserrbuf, sizeof(wserrbuf));
    if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
                      handleDLL,
                      err,
                      MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
                      wserrbuf,
                      sizeof(wserrbuf) - 1,
                      NULL) == 0)
    {
        /* Failed to get id */
        sprintf(wserrbuf, "unrecognized winsock error %d", err);
    }
    return wserrbuf;
}

void pgwin32_unsetenv ( const char *   ) 

Definition at line 154 of file win32env.c.

References free, malloc, and pgwin32_putenv().

{
    char       *envbuf;

    envbuf = (char *) malloc(strlen(name) + 2);
    if (!envbuf)
        return;

    sprintf(envbuf, "%s=", name);
    pgwin32_putenv(envbuf);
    free(envbuf);
}

int pgwin32_waitforsinglesocket ( SOCKET  s,
int  what,
int  timeout 
)

Definition at line 132 of file socket.c.

References buf, ereport, errmsg_internal(), ERROR, FALSE, isDataGram(), NULL, pgwin32_dispatch_queued_signals(), pgwin32_signal_event, TranslateSocketError(), and TRUE.

Referenced by pgwin32_connect(), pgwin32_recv(), pgwin32_send(), secure_read(), and secure_write().

{
    static HANDLE waitevent = INVALID_HANDLE_VALUE;
    static SOCKET current_socket = -1;
    static int  isUDP = 0;
    HANDLE      events[2];
    int         r;

    /* Create an event object just once and use it on all future calls */
    if (waitevent == INVALID_HANDLE_VALUE)
    {
        waitevent = CreateEvent(NULL, TRUE, FALSE, NULL);

        if (waitevent == INVALID_HANDLE_VALUE)
            ereport(ERROR,
                    (errmsg_internal("could not create socket waiting event: error code %lu", GetLastError())));
    }
    else if (!ResetEvent(waitevent))
        ereport(ERROR,
                (errmsg_internal("could not reset socket waiting event: error code %lu", GetLastError())));

    /*
     * Track whether socket is UDP or not.  (NB: most likely, this is both
     * useless and wrong; there is no reason to think that the behavior of
     * WSAEventSelect is different for TCP and UDP.)
     */
    if (current_socket != s)
        isUDP = isDataGram(s);
    current_socket = s;

    /*
     * Attach event to socket.  NOTE: we must detach it again before
     * returning, since other bits of code may try to attach other events to
     * the socket.
     */
    if (WSAEventSelect(s, waitevent, what) != 0)
    {
        TranslateSocketError();
        return 0;
    }

    events[0] = pgwin32_signal_event;
    events[1] = waitevent;

    /*
     * Just a workaround of unknown locking problem with writing in UDP socket
     * under high load: Client's pgsql backend sleeps infinitely in
     * WaitForMultipleObjectsEx, pgstat process sleeps in pgwin32_select().
     * So, we will wait with small timeout(0.1 sec) and if sockect is still
     * blocked, try WSASend (see comments in pgwin32_select) and wait again.
     */
    if ((what & FD_WRITE) && isUDP)
    {
        for (;;)
        {
            r = WaitForMultipleObjectsEx(2, events, FALSE, 100, TRUE);

            if (r == WAIT_TIMEOUT)
            {
                char        c;
                WSABUF      buf;
                DWORD       sent;

                buf.buf = &c;
                buf.len = 0;

                r = WSASend(s, &buf, 1, &sent, 0, NULL, NULL);
                if (r == 0)     /* Completed - means things are fine! */
                {
                    WSAEventSelect(s, NULL, 0);
                    return 1;
                }
                else if (WSAGetLastError() != WSAEWOULDBLOCK)
                {
                    TranslateSocketError();
                    WSAEventSelect(s, NULL, 0);
                    return 0;
                }
            }
            else
                break;
        }
    }
    else
        r = WaitForMultipleObjectsEx(2, events, FALSE, timeout, TRUE);

    WSAEventSelect(s, NULL, 0);

    if (r == WAIT_OBJECT_0 || r == WAIT_IO_COMPLETION)
    {
        pgwin32_dispatch_queued_signals();
        errno = EINTR;
        return 0;
    }
    if (r == WAIT_OBJECT_0 + 1)
        return 1;
    if (r == WAIT_TIMEOUT)
    {
        errno = EWOULDBLOCK;
        return 0;
    }
    ereport(ERROR,
            (errmsg_internal("unrecognized return value from WaitForMultipleObjects: %d (error code %lu)", r, GetLastError())));
    return 0;
}

int setitimer ( int  which,
const struct itimerval value,
struct itimerval ovalue 
)

Definition at line 86 of file timer.c.

References Assert, timerCA::crit_sec, ereport, errmsg_internal(), timerCA::event, FALSE, FATAL, itimerval::it_interval, ITIMER_REAL, MemSet, NULL, pg_timer_thread(), timerThreadHandle, TRUE, and timerCA::value.

Referenced by disable_all_timeouts(), fork_process(), and schedule_alarm().

{
    Assert(value != NULL);
    Assert(value->it_interval.tv_sec == 0 && value->it_interval.tv_usec == 0);
    Assert(which == ITIMER_REAL);

    if (timerThreadHandle == INVALID_HANDLE_VALUE)
    {
        /* First call in this backend, create event and the timer thread */
        timerCommArea.event = CreateEvent(NULL, TRUE, FALSE, NULL);
        if (timerCommArea.event == NULL)
            ereport(FATAL,
             (errmsg_internal("could not create timer event: error code %lu",
                              GetLastError())));

        MemSet(&timerCommArea.value, 0, sizeof(struct itimerval));

        InitializeCriticalSection(&timerCommArea.crit_sec);

        timerThreadHandle = CreateThread(NULL, 0, pg_timer_thread, NULL, 0, NULL);
        if (timerThreadHandle == INVALID_HANDLE_VALUE)
            ereport(FATAL,
            (errmsg_internal("could not create timer thread: error code %lu",
                             GetLastError())));
    }

    /* Request the timer thread to change settings */
    EnterCriticalSection(&timerCommArea.crit_sec);
    if (ovalue)
        *ovalue = timerCommArea.value;
    timerCommArea.value = *value;
    LeaveCriticalSection(&timerCommArea.crit_sec);
    SetEvent(timerCommArea.event);

    return 0;
}


Variable Documentation

PGDLLIMPORT int pg_signal_mask

Definition at line 25 of file signal.c.

Referenced by pgwin32_signal_initialize(), and pqsigsetmask().

PGDLLIMPORT volatile int pg_signal_queue

Definition at line 28 of file signal.c.

Referenced by pg_signal_thread().

Definition at line 28 of file socket.c.

Referenced by PgstatCollectorMain(), pgwin32_recv(), pgwin32_send(), and pq_set_nonblocking().