*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.47 2000/02/27 07:44:22 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.48 2000/03/11 03:08:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
int
Pg_conndefaults(ClientData cData, Tcl_Interp *interp, int argc, char **argv)
{
+ PQconninfoOption *options = PQconndefaults();
PQconninfoOption *option;
Tcl_DString result;
char ibuf[32];
- Tcl_DStringInit(&result);
- for (option = PQconndefaults(); option->keyword != NULL; option++)
+ if (options)
{
- char *val = option->val ? option->val : "";
+ Tcl_DStringInit(&result);
- sprintf(ibuf, "%d", option->dispsize);
- Tcl_DStringStartSublist(&result);
- Tcl_DStringAppendElement(&result, option->keyword);
- Tcl_DStringAppendElement(&result, option->label);
- Tcl_DStringAppendElement(&result, option->dispchar);
- Tcl_DStringAppendElement(&result, ibuf);
- Tcl_DStringAppendElement(&result, val);
- Tcl_DStringEndSublist(&result);
+ for (option = options; option->keyword != NULL; option++)
+ {
+ char *val = option->val ? option->val : "";
+
+ sprintf(ibuf, "%d", option->dispsize);
+ Tcl_DStringStartSublist(&result);
+ Tcl_DStringAppendElement(&result, option->keyword);
+ Tcl_DStringAppendElement(&result, option->label);
+ Tcl_DStringAppendElement(&result, option->dispchar);
+ Tcl_DStringAppendElement(&result, ibuf);
+ Tcl_DStringAppendElement(&result, val);
+ Tcl_DStringEndSublist(&result);
+ }
+ Tcl_DStringResult(interp, &result);
+
+ PQconninfoFree(options);
}
- Tcl_DStringResult(interp, &result);
return TCL_OK;
}
* exceed INITIAL_EXPBUFFER_SIZE (currently 256 bytes).
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.37 2000/02/07 23:10:08 petere Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-auth.c,v 1.38 2000/03/11 03:08:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* allowed. Unauthenticated connections are disallowed unless there
* isn't any authentication system.
*/
-static struct authsvc authsvcs[] = {
+static const struct authsvc authsvcs[] = {
#ifdef KRB4
{"krb4", STARTUP_KRB4_MSG, 1},
{"kerberos", STARTUP_KRB4_MSG, 1},
{"password", STARTUP_PASSWORD_MSG, 0}
};
-static int n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
+static const int n_authsvcs = sizeof(authsvcs) / sizeof(struct authsvc);
#ifdef KRB4
/*----------------------------------------------------------------
*
* Set/return the authentication service currently selected for use by the
* frontend. (You can only use one in the frontend, obviously.)
+ *
+ * NB: This is not thread-safe if different threads try to select different
+ * authentication services! It's OK for fe_getauthsvc to select the default,
+ * since that will be the same for all threads, but direct application use
+ * of fe_setauthsvc is not thread-safe. However, use of fe_setauthsvc is
+ * deprecated anyway...
*/
+
static int pg_authsvc = -1;
void
int i;
for (i = 0; i < n_authsvcs; ++i)
- if (!strcmp(name, authsvcs[i].name))
+ if (strcmp(name, authsvcs[i].name) == 0)
{
pg_authsvc = i;
break;
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.122 2000/02/24 15:53:12 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.123 2000/03/11 03:08:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
} state;
PGconn *conn;
PGresult *res;
- struct EnvironmentOptions *eo;
+ const struct EnvironmentOptions *eo;
} ;
-static int connectDBStart(PGconn *conn);
-static int connectDBComplete(PGconn *conn);
-
#ifdef USE_SSL
static SSL_CTX *SSL_context = NULL;
#endif
-static PGconn *makeEmptyPGconn(void);
-static void freePGconn(PGconn *conn);
-static void closePGconn(PGconn *conn);
-static int conninfo_parse(const char *conninfo, PQExpBuffer errorMessage);
-static char *conninfo_getval(char *keyword);
-static void conninfo_free(void);
-static void defaultNoticeProcessor(void *arg, const char *message);
-
#define NOTIFYLIST_INITIAL_SIZE 10
#define NOTIFYLIST_GROWBY 10
/* ----------
* Definition of the conninfo parameters and their fallback resources.
+ *
* If Environment-Var and Compiled-in are specified as NULL, no
* fallback is available. If after all no value can be determined
* for an option, an error is returned.
*
- * The values for dbname and user are treated special in conninfo_parse.
+ * The values for dbname and user are treated specially in conninfo_parse.
* If the Compiled-in resource is specified as a NULL value, the
* user is determined by fe_getauthname() and for dbname the user
* name is copied.
* The Label and Disp-Char entries are provided for applications that
* want to use PQconndefaults() to create a generic database connection
* dialog. Disp-Char is defined as follows:
- * "" Normal input field
+ * "" Normal input field
+ * "*" Password field - hide value
+ * "D" Debug option - don't show by default
+ *
+ * PQconninfoOptions[] is a constant static array that we use to initialize
+ * a dynamically allocated working copy. All the "val" fields in
+ * PQconninfoOptions[] *must* be NULL. In a working copy, non-null "val"
+ * fields point to malloc'd strings that should be freed when the working
+ * array is freed (see PQconninfoFree).
* ----------
*/
-static PQconninfoOption PQconninfoOptions[] = {
-/* ----------------------------------------------------------------- */
-/* Option-name Environment-Var Compiled-in Current value */
-/* Label Disp-Char */
-/* ----------------- --------------- --------------- --------------- */
- /* "authtype" is ignored as it is no longer used. */
+static const PQconninfoOption PQconninfoOptions[] = {
+ /* "authtype" is no longer used, so mark it "don't show". We keep it
+ * in the array so as not to reject conninfo strings from old apps that
+ * might still try to set it.
+ */
{"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,
- "Database-Authtype", "", 20},
+ "Database-Authtype", "D", 20},
{"user", "PGUSER", NULL, NULL,
"Database-User", "", 20},
{"password", "PGPASSWORD", DefaultPassword, NULL,
- "Database-Password", "", 20},
+ "Database-Password", "*", 20},
{"dbname", "PGDATABASE", NULL, NULL,
"Database-Name", "", 20},
{"options", "PGOPTIONS", DefaultOption, NULL,
"Backend-Debug-Options", "D", 40},
-/* ----------------- --------------- --------------- --------------- */
+
+ /* Terminating entry --- MUST BE LAST */
{NULL, NULL, NULL, NULL,
NULL, NULL, 0}
};
-static struct EnvironmentOptions
+static const struct EnvironmentOptions
{
const char *envName,
*pgName;
};
+static int connectDBStart(PGconn *conn);
+static int connectDBComplete(PGconn *conn);
+static PGconn *makeEmptyPGconn(void);
+static void freePGconn(PGconn *conn);
+static void closePGconn(PGconn *conn);
+static PQconninfoOption *conninfo_parse(const char *conninfo,
+ PQExpBuffer errorMessage);
+static char *conninfo_getval(PQconninfoOption *connOptions,
+ const char *keyword);
+static void defaultNoticeProcessor(void *arg, const char *message);
+
+
/* ----------------
* Connecting to a Database
*
PQconnectStart(const char *conninfo)
{
PGconn *conn;
+ PQconninfoOption *connOptions;
char *tmp;
/* ----------
return (PGconn *) NULL;
/* ----------
- * Parse the conninfo string and save settings in conn structure
+ * Parse the conninfo string
* ----------
*/
- if (conninfo_parse(conninfo, &conn->errorMessage) < 0)
+ connOptions = conninfo_parse(conninfo, &conn->errorMessage);
+ if (connOptions == NULL)
{
conn->status = CONNECTION_BAD;
- conninfo_free();
+ /* errorMessage is already set */
return conn;
}
- tmp = conninfo_getval("hostaddr");
+
+ /*
+ * Move option values into conn structure
+ */
+ tmp = conninfo_getval(connOptions, "hostaddr");
conn->pghostaddr = tmp ? strdup(tmp) : NULL;
- tmp = conninfo_getval("host");
+ tmp = conninfo_getval(connOptions, "host");
conn->pghost = tmp ? strdup(tmp) : NULL;
- tmp = conninfo_getval("port");
+ tmp = conninfo_getval(connOptions, "port");
conn->pgport = tmp ? strdup(tmp) : NULL;
- tmp = conninfo_getval("tty");
+ tmp = conninfo_getval(connOptions, "tty");
conn->pgtty = tmp ? strdup(tmp) : NULL;
- tmp = conninfo_getval("options");
+ tmp = conninfo_getval(connOptions, "options");
conn->pgoptions = tmp ? strdup(tmp) : NULL;
- tmp = conninfo_getval("dbname");
+ tmp = conninfo_getval(connOptions, "dbname");
conn->dbName = tmp ? strdup(tmp) : NULL;
- tmp = conninfo_getval("user");
+ tmp = conninfo_getval(connOptions, "user");
conn->pguser = tmp ? strdup(tmp) : NULL;
- tmp = conninfo_getval("password");
+ tmp = conninfo_getval(connOptions, "password");
conn->pgpass = tmp ? strdup(tmp) : NULL;
/* ----------
- * Free the connection info - all is in conn now
+ * Free the option info - all is in conn now
* ----------
*/
- conninfo_free();
+ PQconninfoFree(connOptions);
/* ----------
* Connect to the database
* PQconndefaults
*
* Parse an empty string like PQconnectdb() would do and return the
- * address of the connection options structure. Using this function
- * an application might determine all possible options and their
- * current default values.
+ * working connection options array.
+ *
+ * Using this function, an application may determine all possible options
+ * and their current default values.
+ *
+ * NOTE: as of PostgreSQL 7.0, the returned array is dynamically allocated
+ * and should be freed when no longer needed via PQconninfoFree(). (In prior
+ * versions, the returned array was static, but that's not thread-safe.)
+ * Pre-7.0 applications that use this function will see a small memory leak
+ * until they are updated to call PQconninfoFree.
* ----------------
*/
PQconninfoOption *
PQconndefaults(void)
{
PQExpBufferData errorBuf;
+ PQconninfoOption *connOptions;
initPQExpBuffer(&errorBuf);
- conninfo_parse("", &errorBuf);
+ connOptions = conninfo_parse("", &errorBuf);
termPQExpBuffer(&errorBuf);
- return PQconninfoOptions;
+ return connOptions;
}
/* ----------------
{
printfPQExpBuffer(&conn->errorMessage,
"connectDBStart() -- "
- "non-tcp access only possible on "
+ "non-TCP access only possible on "
"localhost\n");
return 1;
}
/* ----------------
* Conninfo parser routine
+ *
+ * If successful, a malloc'd PQconninfoOption array is returned.
+ * If not successful, NULL is returned and an error message is
+ * left in errorMessage.
* ----------------
*/
-static int
+static PQconninfoOption *
conninfo_parse(const char *conninfo, PQExpBuffer errorMessage)
{
char *pname;
char *tmp;
char *cp;
char *cp2;
+ PQconninfoOption *options;
PQconninfoOption *option;
char errortmp[INITIAL_EXPBUFFER_SIZE];
- conninfo_free();
+ /* Make a working copy of PQconninfoOptions */
+ options = malloc(sizeof(PQconninfoOptions));
+ if (options == NULL)
+ {
+ printfPQExpBuffer(errorMessage,
+ "FATAL: cannot allocate memory for copy of PQconninfoOptions\n");
+ return NULL;
+ }
+ memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
+ /* Need a modifiable copy of the input string */
if ((buf = strdup(conninfo)) == NULL)
{
printfPQExpBuffer(errorMessage,
"FATAL: cannot allocate memory for copy of conninfo string\n");
- return -1;
+ PQconninfoFree(options);
+ return NULL;
}
cp = buf;
if (*cp != '=')
{
printfPQExpBuffer(errorMessage,
- "ERROR: PQconnectdb() - Missing '=' after '%s' in conninfo\n",
+ "ERROR: Missing '=' after '%s' in conninfo\n",
pname);
+ PQconninfoFree(options);
free(buf);
- return -1;
+ return NULL;
}
*cp++ = '\0';
cp++;
}
+ /* Get the parameter value */
pval = cp;
if (*cp != '\'')
{
printfPQExpBuffer(errorMessage,
"ERROR: PQconnectdb() - unterminated quoted string in conninfo\n");
+ PQconninfoFree(options);
free(buf);
- return -1;
+ return NULL;
}
if (*cp == '\\')
{
* for the param record.
* ----------
*/
- for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ for (option = options; option->keyword != NULL; option++)
{
- if (!strcmp(option->keyword, pname))
+ if (strcmp(option->keyword, pname) == 0)
break;
}
if (option->keyword == NULL)
{
printfPQExpBuffer(errorMessage,
- "ERROR: PQconnectdb() - unknown option '%s'\n",
+ "ERROR: Unknown conninfo option '%s'\n",
pname);
+ PQconninfoFree(options);
free(buf);
- return -1;
+ return NULL;
}
/* ----------
* Store the value
* ----------
*/
+ if (option->val)
+ free(option->val);
option->val = strdup(pval);
}
+ /* Done with the modifiable input string */
free(buf);
/* ----------
* in the conninfo string.
* ----------
*/
- for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ for (option = options; option->keyword != NULL; option++)
{
if (option->val != NULL)
continue; /* Value was in conninfo */
* Special handling for user
* ----------
*/
- if (!strcmp(option->keyword, "user"))
+ if (strcmp(option->keyword, "user") == 0)
{
option->val = fe_getauthname(errortmp);
/* note any error message is thrown away */
* Special handling for dbname
* ----------
*/
- if (!strcmp(option->keyword, "dbname"))
+ if (strcmp(option->keyword, "dbname") == 0)
{
- tmp = conninfo_getval("user");
+ tmp = conninfo_getval(options, "user");
if (tmp)
option->val = strdup(tmp);
continue;
}
}
- return 0;
+ return options;
}
static char *
-conninfo_getval(char *keyword)
+conninfo_getval(PQconninfoOption *connOptions,
+ const char *keyword)
{
PQconninfoOption *option;
- for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ for (option = connOptions; option->keyword != NULL; option++)
{
- if (!strcmp(option->keyword, keyword))
+ if (strcmp(option->keyword, keyword) == 0)
return option->val;
}
}
-static void
-conninfo_free()
+void
+PQconninfoFree(PQconninfoOption *connOptions)
{
PQconninfoOption *option;
- for (option = PQconninfoOptions; option->keyword != NULL; option++)
+ if (connOptions == NULL)
+ return;
+
+ for (option = connOptions; option->keyword != NULL; option++)
{
if (option->val != NULL)
- {
free(option->val);
- option->val = NULL;
- }
}
+ free(connOptions);
}
/* =========== accessor functions for PGconn ========= */
char *
PQerrorMessage(const PGconn *conn)
{
- static char noConn[] = "PQerrorMessage: conn pointer is NULL\n";
-
if (!conn)
- return noConn;
+ return "PQerrorMessage: conn pointer is NULL\n";
+
return conn->errorMessage.data;
}
PQsetNoticeProcessor(PGconn *conn, PQnoticeProcessor proc, void *arg)
{
PQnoticeProcessor old;
+
if (conn == NULL)
return NULL;
old = conn->noticeHook;
- if (proc) {
- conn->noticeHook = proc;
- conn->noticeArg = arg;
+ if (proc)
+ {
+ conn->noticeHook = proc;
+ conn->noticeArg = arg;
}
return old;
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.91 2000/02/24 04:50:51 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.92 2000/03/11 03:08:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
};
+/* Note: DONOTICE macro will work if applied to either PGconn or PGresult */
#define DONOTICE(conn,message) \
((*(conn)->noticeHook) ((conn)->noticeArg, (message)))
result = (PGresult *) malloc(sizeof(PGresult));
- result->conn = conn; /* might be NULL */
+ result->xconn = conn; /* might be NULL */
result->ntups = 0;
result->numAttributes = 0;
result->attDescs = NULL;
result->curOffset = 0;
result->spaceLeft = 0;
- if (conn) /* consider copying conn's errorMessage */
+ if (conn)
{
+ result->noticeHook = conn->noticeHook;
+ result->noticeArg = conn->noticeArg;
+ /* consider copying conn's errorMessage */
switch (status)
{
case PGRES_EMPTY_QUERY:
break;
}
}
+ else
+ {
+ result->noticeHook = NULL;
+ result->noticeArg = NULL;
+ }
+
return result;
}
return FALSE; /* no way to display error message... */
if (field_num < 0 || field_num >= res->numAttributes)
{
- if (res->conn)
+ if (res->noticeHook)
{
sprintf(noticeBuf,
"%s: ERROR! field number %d is out of range 0..%d\n",
routineName, field_num, res->numAttributes - 1);
- DONOTICE(res->conn, noticeBuf);
+ DONOTICE(res, noticeBuf);
}
return FALSE;
}
return FALSE; /* no way to display error message... */
if (tup_num < 0 || tup_num >= res->ntups)
{
- if (res->conn)
+ if (res->noticeHook)
{
sprintf(noticeBuf,
"%s: ERROR! tuple number %d is out of range 0..%d\n",
routineName, tup_num, res->ntups - 1);
- DONOTICE(res->conn, noticeBuf);
+ DONOTICE(res, noticeBuf);
}
return FALSE;
}
if (field_num < 0 || field_num >= res->numAttributes)
{
- if (res->conn)
+ if (res->noticeHook)
{
sprintf(noticeBuf,
"%s: ERROR! field number %d is out of range 0..%d\n",
routineName, field_num, res->numAttributes - 1);
- DONOTICE(res->conn, noticeBuf);
+ DONOTICE(res, noticeBuf);
}
return FALSE;
}
char *
PQoidStatus(const PGresult *res)
{
- /*
- * This must be enough to hold the result. Don't laugh, this is
- * better than what this function used to do.
- */
- static char buf[24];
+ /*
+ * This must be enough to hold the result. Don't laugh, this is
+ * better than what this function used to do.
+ */
+ static char buf[24];
size_t len;
len = strspn(res->cmdStatus + 7, "0123456789");
if (len > 23)
- len = 23;
+ len = 23;
strncpy(buf, res->cmdStatus + 7, len);
buf[23] = '\0';
if (*p == 0)
{
- if (res->conn)
+ if (res->noticeHook)
{
sprintf(noticeBuf,
"PQcmdTuples (%s) -- bad input from server\n",
res->cmdStatus);
- DONOTICE(res->conn, noticeBuf);
+ DONOTICE(res, noticeBuf);
}
return "";
}
p++; /* INSERT: skip oid */
if (*p == 0)
{
- if (res->conn)
+ if (res->noticeHook)
{
sprintf(noticeBuf,
"PQcmdTuples (INSERT) -- there's no # of tuples\n");
- DONOTICE(res->conn, noticeBuf);
+ DONOTICE(res, noticeBuf);
}
return "";
}
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-fe.h,v 1.60 2000/02/07 23:10:11 petere Exp $
+ * $Id: libpq-fe.h,v 1.61 2000/03/11 03:08:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* ----------------
* Structure for the conninfo parameter definitions returned by PQconndefaults
+ *
+ * All fields except "val" point at static strings which must not be altered.
+ * "val" is either NULL or a malloc'd current-value string. PQconninfoFree()
+ * will release both the val strings and the PQconninfoOption array itself.
* ----------------
*/
typedef struct _PQconninfoOption
char *keyword; /* The keyword of the option */
char *envvar; /* Fallback environment variable name */
char *compiled; /* Fallback compiled in default value */
- char *val; /* Options value */
+ char *val; /* Option's current value, or NULL */
char *label; /* Label for field in connect dialog */
- char *dispchar; /* Character to display for this field */
- /* in a connect dialog. Values are: */
- /* "" Display entered value as is */
- /* "*" Password field - hide value */
- /* "D" Debug options - don't */
- /* create a field by default */
+ char *dispchar; /* Character to display for this field
+ * in a connect dialog. Values are:
+ * "" Display entered value as is
+ * "*" Password field - hide value
+ * "D" Debug option - don't show by default
+ */
int dispsize; /* Field size in characters for dialog */
} PQconninfoOption;
#define PQsetdb(M_PGHOST,M_PGPORT,M_PGOPT,M_PGTTY,M_DBNAME) \
PQsetdbLogin(M_PGHOST, M_PGPORT, M_PGOPT, M_PGTTY, M_DBNAME, NULL, NULL)
+ /* close the current connection and free the PGconn data structure */
+ extern void PQfinish(PGconn *conn);
+
/* get info about connection options known to PQconnectdb */
extern PQconninfoOption *PQconndefaults(void);
- /* close the current connection and free the PGconn data structure */
- extern void PQfinish(PGconn *conn);
+ /* free the data structure returned by PQconndefaults() */
+ extern void PQconninfoFree(PQconninfoOption *connOptions);
/*
* close the current connection and restablish a new one with the same
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq-int.h,v 1.19 2000/02/07 23:10:11 petere Exp $
+ * $Id: libpq-int.h,v 1.20 2000/03/11 03:08:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* last query */
int binary; /* binary tuple values if binary == 1,
* otherwise ASCII */
- PGconn *conn; /* connection we did the query on, if any */
+ /*
+ * The conn link in PGresult is no longer used by any libpq code.
+ * It should be removed entirely, because it could be a dangling link
+ * (the application could keep the PGresult around longer than it keeps
+ * the PGconn!) But there may be apps out there that depend on it,
+ * so we will leave it here at least for a release or so.
+ */
+ PGconn *xconn; /* connection we did the query on, if any */
+
+ /* Callback procedure for notice/error message processing
+ * (copied from originating PGconn).
+ */
+ PQnoticeProcessor noticeHook;
+ void *noticeArg;
+
char *errMsg; /* error message, or NULL if no error */
/* All NULL attributes in the query result point to this null string */
appendPQExpBufferStr @ 75
destroyPQExpBuffer @ 76
createPQExpBuffer @ 77
+ PQconninfoFree @ 78
/*-------------------------------------------------------
*
- * $Id: Pg.xs,v 1.13 1999/10/13 02:26:37 momjian Exp $ with patch for NULs
+ * $Id: Pg.xs,v 1.14 2000/03/11 03:08:37 tgl Exp $ with patch for NULs
*
* Copyright (c) 1997, 1998 Edmund Mergl
*
HV *
PQconndefaults()
CODE:
- PQconninfoOption *infoOption;
+ PQconninfoOption *infoOptions;
RETVAL = newHV();
- if (infoOption = PQconndefaults()) {
- while (infoOption->keyword != NULL) {
- if (infoOption->val != NULL) {
- hv_store(RETVAL, infoOption->keyword, strlen(infoOption->keyword), newSVpv(infoOption->val, 0), 0);
+ if (infoOptions = PQconndefaults()) {
+ PQconninfoOption *option;
+ for (option = infoOptions; option->keyword != NULL; option++) {
+ if (option->val != NULL) {
+ hv_store(RETVAL, option->keyword, strlen(option->keyword), newSVpv(option->val, 0), 0);
} else {
- hv_store(RETVAL, infoOption->keyword, strlen(infoOption->keyword), newSVpv("", 0), 0);
+ hv_store(RETVAL, option->keyword, strlen(option->keyword), newSVpv("", 0), 0);
}
- infoOption++;
}
+ PQconninfoFree(infoOptions);
}
OUTPUT:
RETVAL
HV *
conndefaults()
CODE:
- PQconninfoOption *infoOption;
+ PQconninfoOption *infoOptions;
RETVAL = newHV();
- if (infoOption = PQconndefaults()) {
- while (infoOption->keyword != NULL) {
- if (infoOption->val != NULL) {
- hv_store(RETVAL, infoOption->keyword, strlen(infoOption->keyword), newSVpv(infoOption->val, 0), 0);
+ if (infoOptions = PQconndefaults()) {
+ PQconninfoOption *option;
+ for (option = infoOptions; option->keyword != NULL; option++) {
+ if (option->val != NULL) {
+ hv_store(RETVAL, option->keyword, strlen(option->keyword), newSVpv(option->val, 0), 0);
} else {
- hv_store(RETVAL, infoOption->keyword, strlen(infoOption->keyword), newSVpv("", 0), 0);
+ hv_store(RETVAL, option->keyword, strlen(option->keyword), newSVpv("", 0), 0);
}
- infoOption++;
}
+ PQconninfoFree(infoOptions);
}
OUTPUT:
RETVAL