X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=src%2Finterfaces%2Flibpq%2Flibpq-int.h;h=adeaa35d0bf46304667fb3d9f5f71b7b373e1ab5;hb=c89404edf3f3b35a4a599d71f407055bda8261b6;hp=97cd55eaa8ad93e9ed3dfe42b2091999c444889d;hpb=0150dbdce54f24596547048d4d6617d62a2570a4;p=postgresql diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h index 97cd55eaa8..adeaa35d0b 100644 --- a/src/interfaces/libpq/libpq-int.h +++ b/src/interfaces/libpq/libpq-int.h @@ -9,10 +9,10 @@ * more likely to break across PostgreSQL releases than code that uses * only the official API. * - * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.84 2004/01/09 02:02:43 momjian Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.137 2008/11/13 09:45:25 mha Exp $ * *------------------------------------------------------------------------- */ @@ -22,6 +22,7 @@ /* We assume libpq-fe.h has already been included. */ #include "postgres_fe.h" +#include "libpq-events.h" #include #include @@ -30,21 +31,45 @@ #endif #ifdef ENABLE_THREAD_SAFETY +#ifdef WIN32 +#include "pthread-win32.h" +#else #include #endif - -#if defined(WIN32) && (!defined(ssize_t)) -typedef int ssize_t; /* ssize_t doesn't exist in VC (at least - * not VC6) */ +#include #endif /* include stuff common to fe and be */ #include "getaddrinfo.h" #include "libpq/pqcomm.h" -#include "lib/dllist.h" /* include stuff found in fe only */ #include "pqexpbuffer.h" +#ifdef ENABLE_GSS +#if defined(HAVE_GSSAPI_H) +#include +#else +#include +#endif +#endif + +#ifdef ENABLE_SSPI +#define SECURITY_WIN32 +#include +#undef SECURITY_WIN32 + +#ifndef ENABLE_GSS +/* + * Define a fake structure compatible with GSSAPI on Unix. + */ +typedef struct +{ + void *value; + int length; +} gss_buffer_desc; +#endif +#endif /* ENABLE_SSPI */ + #ifdef USE_SSL #include #include @@ -53,8 +78,7 @@ typedef int ssize_t; /* ssize_t doesn't exist in VC (at least /* * POSTGRES backend dependent Constants. */ -#define PQERRORMSG_LENGTH 1024 -#define CMDSTATUS_LEN 40 +#define CMDSTATUS_LEN 64 /* should match COMPLETION_TAG_BUFSIZE */ /* * PGresult and the subsidiary types PGresAttDesc, PGresAttValue @@ -77,18 +101,11 @@ union pgresult_data char space[1]; /* dummy for accessing block as bytes */ }; -/* Data about a single attribute (column) of a query result */ - -typedef struct pgresAttDesc +/* Data about a single parameter of a prepared statement */ +typedef struct pgresParamDesc { - char *name; /* column name */ - Oid tableid; /* source table, if known */ - int columnid; /* source column, if known */ - int format; /* format code for value (text/binary) */ Oid typid; /* type id */ - int typlen; /* type size */ - int atttypmod; /* type-specific modifier info */ -} PGresAttDesc; +} PGresParamDesc; /* * Data for a single attribute of a single tuple @@ -113,9 +130,8 @@ typedef struct pgresAttDesc typedef struct pgresAttValue { int len; /* length in bytes of the value */ - char *value; /* actual value, plus terminating zero - * byte */ -} PGresAttValue; + char *value; /* actual value, plus terminating zero byte */ +} PGresAttValue; /* Typedef for message-field list entries */ typedef struct pgMessageField @@ -123,7 +139,7 @@ typedef struct pgMessageField struct pgMessageField *next; /* list link */ char code; /* field code */ char contents[1]; /* field value (VARIABLE LENGTH) */ -} PGMessageField; +} PGMessageField; /* Fields needed for notice handling */ typedef struct @@ -132,7 +148,16 @@ typedef struct void *noticeRecArg; PQnoticeProcessor noticeProc; /* notice message processor */ void *noticeProcArg; -} PGNoticeHooks; +} PGNoticeHooks; + +typedef struct PGEvent +{ + PGEventProc proc; /* the function to call on events */ + char *name; /* used only for error messages */ + void *passThrough; /* pointer supplied at registration time */ + void *data; /* optional state (instance) data */ + bool resultInitialized; /* T if RESULTCREATE/COPY succeeded */ +} PGEvent; struct pg_result { @@ -142,23 +167,26 @@ struct pg_result PGresAttValue **tuples; /* each PGresTuple is an array of * PGresAttValue's */ int tupArrSize; /* allocated size of tuples array */ + int numParameters; + PGresParamDesc *paramDescs; ExecStatusType resultStatus; - char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the - * query */ + char cmdStatus[CMDSTATUS_LEN]; /* cmd status from the query */ int binary; /* binary tuple values if binary == 1, * otherwise text */ /* - * These fields are copied from the originating PGconn, so that - * operations on the PGresult don't have to reference the PGconn. + * These fields are copied from the originating PGconn, so that operations + * on the PGresult don't have to reference the PGconn. */ PGNoticeHooks noticeHooks; + PGEvent *events; + int nEvents; int client_encoding; /* encoding id */ /* * Error information (all NULL if not an error result). errMsg is the - * "overall" error message returned by PQresultErrorMessage. If we - * have per-field info then it is stored in a linked list. + * "overall" error message returned by PQresultErrorMessage. If we have + * per-field info then it is stored in a linked list. */ char *errMsg; /* error message, or NULL if no error */ PGMessageField *errFields; /* message broken into fields */ @@ -167,8 +195,8 @@ struct pg_result char null_field[1]; /* - * Space management information. Note that attDescs and error stuff, - * if not null, point into allocated blocks. But tuples points to a + * Space management information. Note that attDescs and error stuff, if + * not null, point into allocated blocks. But tuples points to a * separately malloc'd block, so that we can realloc it. */ PGresult_data *curBlock; /* most recently allocated block */ @@ -184,7 +212,16 @@ typedef enum PGASYNC_READY, /* result ready for PQgetResult */ PGASYNC_COPY_IN, /* Copy In data transfer in progress */ PGASYNC_COPY_OUT /* Copy Out data transfer in progress */ -} PGAsyncStatusType; +} PGAsyncStatusType; + +/* PGQueryClass tracks which query protocol we are now executing */ +typedef enum +{ + PGQUERY_SIMPLE, /* simple Query protocol (PQexec) */ + PGQUERY_EXTENDED, /* full Extended protocol (PQexecParams) */ + PGQUERY_PREPARE, /* Parse only (PQprepare) */ + PGQUERY_DESCRIBE /* Describe Statement or Portal */ +} PGQueryClass; /* PGSetenvStatusType defines the state of the PQSetenv state machine */ /* (this is used only for 2.0-protocol connections) */ @@ -197,14 +234,14 @@ typedef enum SETENV_STATE_QUERY2_SEND, /* About to send a status query */ SETENV_STATE_QUERY2_WAIT, /* Waiting for query to complete */ SETENV_STATE_IDLE -} PGSetenvStatusType; +} PGSetenvStatusType; /* Typedef for the EnvironmentOptions[] array */ typedef struct PQEnvironmentOption { const char *envName, /* name of an environment variable */ *pgName; /* name of corresponding SET variable */ -} PQEnvironmentOption; +} PQEnvironmentOption; /* Typedef for parameter-status list entries */ typedef struct pgParameterStatus @@ -213,7 +250,7 @@ typedef struct pgParameterStatus char *name; /* parameter name */ char *value; /* parameter value */ /* Note: name and value are stored in same malloc block as struct is */ -} pgParameterStatus; +} pgParameterStatus; /* large-object-access data ... allocated only if large-object code is used. */ typedef struct pgLobjfuncs @@ -221,12 +258,14 @@ typedef struct pgLobjfuncs Oid fn_lo_open; /* OID of backend function lo_open */ Oid fn_lo_close; /* OID of backend function lo_close */ Oid fn_lo_creat; /* OID of backend function lo_creat */ + Oid fn_lo_create; /* OID of backend function lo_create */ Oid fn_lo_unlink; /* OID of backend function lo_unlink */ Oid fn_lo_lseek; /* OID of backend function lo_lseek */ Oid fn_lo_tell; /* OID of backend function lo_tell */ + Oid fn_lo_truncate; /* OID of backend function lo_truncate */ Oid fn_lo_read; /* OID of backend function LOread */ Oid fn_lo_write; /* OID of backend function LOwrite */ -} PGlobjfuncs; +} PGlobjfuncs; /* * PGconn stores all the state data associated with a single connection @@ -235,16 +274,15 @@ typedef struct pgLobjfuncs struct pg_conn { /* Saved values of connection options */ - char *pghost; /* the machine on which the server is - * running */ - char *pghostaddr; /* the IPv4 address of the machine on - * which the server is running, in IPv4 - * numbers-and-dots notation. Takes - * precedence over above. */ + char *pghost; /* the machine on which the server is running */ + char *pghostaddr; /* the IPv4 address of the machine on which + * the server is running, in IPv4 + * numbers-and-dots notation. Takes precedence + * over above. */ char *pgport; /* the server's communication port */ - char *pgunixsocket; /* the Unix-domain socket that the server - * is listening on; if NULL, uses a - * default constructed from pgport */ + char *pgunixsocket; /* the Unix-domain socket that the server is + * listening on; if NULL, uses a default + * constructed from pgport */ char *pgtty; /* tty on which the backend messages is * displayed (OBSOLETE, NOT USED) */ char *connect_timeout; /* connection timeout (numeric string) */ @@ -253,6 +291,10 @@ struct pg_conn char *pguser; /* Postgres username and password, if any */ char *pgpass; char *sslmode; /* SSL mode (require,prefer,allow,disable) */ + char *sslverify; /* Verify server SSL certificate (none,chain,cn) */ +#if defined(KRB5) || defined(ENABLE_GSS) || defined(ENABLE_SSPI) + char *krbsrvname; /* Kerberos service name */ +#endif /* Optional file to write trace info to */ FILE *Pfdebug; @@ -260,27 +302,33 @@ struct pg_conn /* Callback procedures for notice message processing */ PGNoticeHooks noticeHooks; + /* Event procs registered via PQregisterEventProc */ + PGEvent *events; /* expandable array of event data */ + int nEvents; /* number of active events */ + int eventArraySize; /* allocated array size */ + /* Status indicators */ ConnStatusType status; PGAsyncStatusType asyncStatus; - PGTransactionStatusType xactStatus; - /* note: xactStatus never changes to ACTIVE */ - bool nonblocking; /* whether this connection is using - * nonblock sending semantics */ - bool ext_query; /* was our last query sent with extended - * query protocol? */ + PGTransactionStatusType xactStatus; /* never changes to ACTIVE */ + PGQueryClass queryclass; + char *last_query; /* last SQL command, or NULL if unknown */ + bool options_valid; /* true if OK to attempt connection */ + bool nonblocking; /* whether this connection is using nonblock + * sending semantics */ char copy_is_binary; /* 1 = copy binary, 0 = copy text */ - int copy_already_done; /* # bytes already returned in - * COPY OUT */ - Dllist *notifyList; /* Notify msgs not yet handed to - * application */ + int copy_already_done; /* # bytes already returned in COPY + * OUT */ + PGnotify *notifyHead; /* oldest unreported Notify msg */ + PGnotify *notifyTail; /* newest unreported Notify msg */ /* Connection data */ int sock; /* Unix FD for socket, -1 if not connected */ SockAddr laddr; /* Local address */ SockAddr raddr; /* Remote address */ ProtocolVersion pversion; /* FE/BE protocol version in use */ - char sversion[8]; /* The first few bytes of server version */ + int sversion; /* server version, e.g. 70401 for 7.4.1 */ + bool password_needed; /* true if server demanded a password */ /* Transient state needed while establishing connection */ struct addrinfo *addrlist; /* list of possible backend addresses */ @@ -293,21 +341,18 @@ struct pg_conn int be_pid; /* PID of backend --- needed for cancels */ int be_key; /* key of backend --- needed for cancels */ char md5Salt[4]; /* password salt received from backend */ - char cryptSalt[2]; /* password salt received from backend */ pgParameterStatus *pstatus; /* ParameterStatus data */ int client_encoding; /* encoding id */ + bool std_strings; /* standard_conforming_strings */ PGVerbosity verbosity; /* error/notice message verbosity */ - PGlobjfuncs *lobjfuncs; /* private state for large-object access - * fns */ + PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */ /* Buffer for data received from backend and not yet processed */ char *inBuffer; /* currently allocated buffer */ int inBufSize; /* allocated size of buffer */ - int inStart; /* offset to first unconsumed data in - * buffer */ + int inStart; /* offset to first unconsumed data in buffer */ int inCursor; /* next byte to tentatively consume */ - int inEnd; /* offset to first position after avail - * data */ + int inEnd; /* offset to first position after avail data */ /* Buffer for data not yet sent to backend */ char *outBuffer; /* currently allocated buffer */ @@ -315,8 +360,8 @@ struct pg_conn int outCount; /* number of chars waiting in buffer */ /* State for constructing messages in outBuffer */ - int outMsgStart; /* offset to msg start (length word); if - * -1, msg has no length word */ + int outMsgStart; /* offset to msg start (length word); if -1, + * msg has no length word */ int outMsgEnd; /* offset to msg end (so far) */ /* Status for asynchronous result construction */ @@ -333,6 +378,28 @@ struct pg_conn char peer_cn[SM_USER + 1]; /* peer common name */ #endif +#ifdef ENABLE_GSS + gss_ctx_id_t gctx; /* GSS context */ + gss_name_t gtarg_nam; /* GSS target name */ + gss_buffer_desc ginbuf; /* GSS input token */ + gss_buffer_desc goutbuf; /* GSS output token */ +#endif + +#ifdef ENABLE_SSPI +#ifndef ENABLE_GSS + gss_buffer_desc ginbuf; /* GSS input token */ +#else + char *gsslib; /* What GSS librart to use ("gssapi" or + * "sspi") */ +#endif + CredHandle *sspicred; /* SSPI credentials handle */ + CtxtHandle *sspictx; /* SSPI context */ + char *sspitarget; /* SSPI target name */ + int usesspi; /* Indicate if SSPI is in use on the + * connection */ +#endif + + /* Buffer for current error message */ PQExpBufferData errorMessage; /* expansible string */ @@ -340,6 +407,18 @@ struct pg_conn PQExpBufferData workBuffer; /* expansible string */ }; +/* PGcancel stores all data necessary to cancel a connection. A copy of this + * data is required to safely cancel a connection running on a different + * thread. + */ +struct pg_cancel +{ + SockAddr raddr; /* Remote address */ + int be_pid; /* PID of backend --- needed for cancels */ + int be_key; /* key of backend --- needed for cancels */ +}; + + /* String descriptions of the ExecStatusTypes. * direct use of this array is deprecated; call PQresStatus() instead. */ @@ -358,6 +437,24 @@ extern char *const pgresStatus[]; extern int pqPacketSend(PGconn *conn, char pack_type, const void *buf, size_t buf_len); +extern bool pqGetHomeDirectory(char *buf, int bufsize); + +#ifdef ENABLE_THREAD_SAFETY +extern pgthreadlock_t pg_g_threadlock; + +#define PGTHREAD_ERROR(msg) \ + do { \ + fprintf(stderr, "%s\n", msg); \ + exit(1); \ + } while (0) + + +#define pglock_thread() pg_g_threadlock(true) +#define pgunlock_thread() pg_g_threadlock(false) +#else +#define pglock_thread() ((void) 0) +#define pgunlock_thread() ((void) 0) +#endif /* === in fe-exec.c === */ @@ -369,10 +466,10 @@ extern void pqClearAsyncResult(PGconn *conn); extern void pqSaveErrorResult(PGconn *conn); extern PGresult *pqPrepareAsyncResult(PGconn *conn); extern void -pqInternalNotice(const PGNoticeHooks * hooks, const char *fmt,...) +pqInternalNotice(const PGNoticeHooks *hooks, const char *fmt,...) /* This lets gcc check the format string for consistency. */ __attribute__((format(printf, 2, 3))); -extern int pqAddTuple(PGresult *res, PGresAttValue * tup); +extern int pqAddTuple(PGresult *res, PGresAttValue *tup); extern void pqSaveMessageField(PGresult *res, char code, const char *value); extern void pqSaveParameterStatus(PGconn *conn, const char *name, @@ -384,7 +481,7 @@ extern void pqHandleSendFailure(PGconn *conn); extern PostgresPollingStatusType pqSetenvPoll(PGconn *conn); extern char *pqBuildStartupPacket2(PGconn *conn, int *packetlen, - const PQEnvironmentOption * options); + const PQEnvironmentOption *options); extern void pqParseInput2(PGconn *conn); extern int pqGetCopyData2(PGconn *conn, char **buffer, int async); extern int pqGetline2(PGconn *conn, char *s, int maxlen); @@ -398,7 +495,7 @@ extern PGresult *pqFunctionCall2(PGconn *conn, Oid fnid, /* === in fe-protocol3.c === */ extern char *pqBuildStartupPacket3(PGconn *conn, int *packetlen, - const PQEnvironmentOption * options); + const PQEnvironmentOption *options); extern void pqParseInput3(PGconn *conn); extern int pqGetErrorNotice3(PGconn *conn, bool isError); extern int pqGetCopyData3(PGconn *conn, char **buffer, int async); @@ -413,15 +510,16 @@ extern PGresult *pqFunctionCall3(PGconn *conn, Oid fnid, /* === in fe-misc.c === */ /* - * "Get" and "Put" routines return 0 if successful, EOF if not. Note that - * for Get, EOF merely means the buffer is exhausted, not that there is + * "Get" and "Put" routines return 0 if successful, EOF if not. Note that for + * Get, EOF merely means the buffer is exhausted, not that there is * necessarily any error. */ -extern int pqCheckOutBufferSpace(int bytes_needed, PGconn *conn); -extern int pqCheckInBufferSpace(int bytes_needed, PGconn *conn); +extern int pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn); +extern int pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn); extern int pqGetc(char *result, PGconn *conn); extern int pqPutc(char c, PGconn *conn); extern int pqGets(PQExpBuffer buf, PGconn *conn); +extern int pqGets_append(PQExpBuffer buf, PGconn *conn); extern int pqPuts(const char *s, PGconn *conn); extern int pqGetnchar(char *s, size_t len, PGconn *conn); extern int pqPutnchar(const char *s, size_t len, PGconn *conn); @@ -445,9 +543,11 @@ extern PostgresPollingStatusType pqsecure_open_client(PGconn *); extern void pqsecure_close(PGconn *); extern ssize_t pqsecure_read(PGconn *, void *ptr, size_t len); extern ssize_t pqsecure_write(PGconn *, const void *ptr, size_t len); -#ifdef ENABLE_THREAD_SAFETY -extern void check_sigpipe_handler(void); -extern pthread_key_t thread_in_send; + +#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32) +extern int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending); +extern void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, + bool got_epipe); #endif /* @@ -460,7 +560,6 @@ extern pthread_key_t thread_in_send; extern char * libpq_gettext(const char *msgid) __attribute__((format_arg(1))); - #else #define libpq_gettext(x) (x) #endif @@ -476,7 +575,7 @@ __attribute__((format_arg(1))); #else #define SOCK_ERRNO errno #define SOCK_STRERROR pqStrerror -#define SOCK_ERRNO_SET(e) errno=e +#define SOCK_ERRNO_SET(e) (errno = (e)) #endif #endif /* LIBPQ_INT_H */