mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
From: Magnus Hagander <mha@sollentuna.net>
Here's another patch for the libpq backend areas. This patch removes all usage of "FILE *" on the communications channel. It also cleans up the comments and headers in the pqcomm.c file - a lot of things were either missing or incorrect. Finally, it removes a couple of unused functions (leftovers from the time of shared code between the libpq backend and frontend).
This commit is contained in:
@@ -5,19 +5,22 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pqcomm.c,v 1.60 1999/01/11 03:56:06 scrappy Exp $
|
* $Id: pqcomm.c,v 1.61 1999/01/12 12:49:51 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
* pq_gettty - return the name of the tty in the given buffer
|
* pq_init - initialize libpq
|
||||||
* pq_getport - return the PGPORT setting
|
* pq_getport - return the PGPORT setting
|
||||||
* pq_close - close input / output connections
|
* pq_close - close input / output connections
|
||||||
* pq_flush - flush pending output
|
* pq_flush - flush pending output
|
||||||
* pq_getstr - get a null terminated string from connection
|
* pq_getstr - get a null terminated string from connection
|
||||||
* pq_getnchar - get n characters from connection
|
* pq_getchar - get 1 character from connection
|
||||||
|
* pq_peekchar - peek at first character in connection
|
||||||
|
* pq_getnchar - get n characters from connection, and null-terminate
|
||||||
* pq_getint - get an integer from connection
|
* pq_getint - get an integer from connection
|
||||||
|
* pq_putchar - send 1 character to connection
|
||||||
* pq_putstr - send a null terminated string to connection
|
* pq_putstr - send a null terminated string to connection
|
||||||
* pq_putnchar - send n characters to connection
|
* pq_putnchar - send n characters to connection
|
||||||
* pq_putint - send an integer to connection
|
* pq_putint - send an integer to connection
|
||||||
@@ -26,12 +29,15 @@
|
|||||||
* the length)
|
* the length)
|
||||||
* pq_getinaddr - initialize address from host and port number
|
* pq_getinaddr - initialize address from host and port number
|
||||||
* pq_getinserv - initialize address from host and service name
|
* pq_getinserv - initialize address from host and service name
|
||||||
* pq_connect - create remote input / output connection
|
|
||||||
* pq_accept - accept remote input / output connection
|
|
||||||
*
|
*
|
||||||
|
* StreamDoUnlink - Shutdown UNIX socket connectioin
|
||||||
|
* StreamServerPort - Open sock stream
|
||||||
|
* StreamConnection - Create new connection with client
|
||||||
|
* StreamClose - Close a client/backend connection
|
||||||
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* These functions are used by both frontend applications and
|
* Frontend is now completey in interfaces/libpq, and no
|
||||||
* the postgres backend.
|
* functions from this file is used.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@@ -71,13 +77,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "utils/trace.h"
|
#include "utils/trace.h"
|
||||||
|
|
||||||
/* ----------------
|
extern FILE * debug_port; /* in util.c */
|
||||||
* declarations
|
|
||||||
* ----------------
|
|
||||||
*/
|
|
||||||
static FILE *Pfout,
|
|
||||||
*Pfin,
|
|
||||||
*Pfdebug; /* debugging libpq */
|
|
||||||
|
|
||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
* pq_init - open portal file descriptors
|
* pq_init - open portal file descriptors
|
||||||
@@ -86,15 +86,9 @@ static FILE *Pfout,
|
|||||||
void
|
void
|
||||||
pq_init(int fd)
|
pq_init(int fd)
|
||||||
{
|
{
|
||||||
Pfin = fdopen(fd, "r");
|
|
||||||
Pfout = fdopen(dup(fd), "w");
|
|
||||||
if (!Pfin || !Pfout)
|
|
||||||
elog(FATAL, "pq_init: Couldn't initialize socket connection");
|
|
||||||
PQnotifies_init();
|
PQnotifies_init();
|
||||||
if (getenv("LIBPQ_DEBUG"))
|
if (getenv("LIBPQ_DEBUG"))
|
||||||
Pfdebug = stderr;
|
debug_port = stderr;
|
||||||
else
|
|
||||||
Pfdebug = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------
|
/* -------------------------
|
||||||
@@ -102,19 +96,23 @@ pq_init(int fd)
|
|||||||
*
|
*
|
||||||
* get a character from the input file,
|
* get a character from the input file,
|
||||||
*
|
*
|
||||||
* if Pfdebug is set, also echo the character fetched into Pfdebug
|
|
||||||
*
|
|
||||||
* used for debugging libpq
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
pq_getchar(void)
|
pq_getchar(void)
|
||||||
{
|
{
|
||||||
int c;
|
char c;
|
||||||
|
char isDone = 0;
|
||||||
|
|
||||||
c = getc(Pfin);
|
do {
|
||||||
if (Pfdebug && c != EOF)
|
if (recv(MyProcPort->sock,&c,1,MSG_WAITALL) != 1) {
|
||||||
putc(c, Pfdebug);
|
if (errno != EINTR)
|
||||||
|
return EOF; /* Not interrupted, so something went wrong */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
isDone = 1;
|
||||||
|
} while (!isDone);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,23 +122,23 @@ pq_getchar(void)
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pq_peekchar(void) {
|
pq_peekchar(void) {
|
||||||
char c = getc(Pfin);
|
char c;
|
||||||
ungetc(c,Pfin);
|
char isDone = 0;
|
||||||
return c;
|
|
||||||
|
do {
|
||||||
|
if (recv(MyProcPort->sock,&c,1,MSG_WAITALL | MSG_PEEK) != 1) {
|
||||||
|
if (errno != EINTR)
|
||||||
|
return EOF; /* Not interrupted, so something went wrong */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
isDone = 1;
|
||||||
|
} while (!isDone);
|
||||||
|
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------
|
|
||||||
* pq_gettty - return the name of the tty in the given buffer
|
|
||||||
* --------------------------------
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
pq_gettty(char *tp)
|
|
||||||
{
|
|
||||||
strncpy(tp, ttyname(0), 19);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
* pq_getport - return the PGPORT setting
|
* pq_getport - return the PGPORT setting
|
||||||
* --------------------------------
|
* --------------------------------
|
||||||
@@ -162,16 +160,7 @@ pq_getport()
|
|||||||
void
|
void
|
||||||
pq_close()
|
pq_close()
|
||||||
{
|
{
|
||||||
if (Pfin)
|
close(MyProcPort->sock);
|
||||||
{
|
|
||||||
fclose(Pfin);
|
|
||||||
Pfin = NULL;
|
|
||||||
}
|
|
||||||
if (Pfout)
|
|
||||||
{
|
|
||||||
fclose(Pfout);
|
|
||||||
Pfout = NULL;
|
|
||||||
}
|
|
||||||
PQnotifies_init();
|
PQnotifies_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,8 +171,7 @@ pq_close()
|
|||||||
void
|
void
|
||||||
pq_flush()
|
pq_flush()
|
||||||
{
|
{
|
||||||
if (Pfout)
|
/* Not supported/required? */
|
||||||
fflush(Pfout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
@@ -198,13 +186,7 @@ pq_getstr(char *s, int maxlen)
|
|||||||
char *p;
|
char *p;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (Pfin == (FILE *) NULL)
|
c = pqGetString(s, maxlen);
|
||||||
{
|
|
||||||
/* elog(DEBUG, "Input descriptor is null"); */
|
|
||||||
return EOF;
|
|
||||||
}
|
|
||||||
|
|
||||||
c = pqGetString(s, maxlen, Pfin);
|
|
||||||
|
|
||||||
#ifdef MULTIBYTE
|
#ifdef MULTIBYTE
|
||||||
p = (char*) pg_client_to_server((unsigned char *) s, maxlen);
|
p = (char*) pg_client_to_server((unsigned char *) s, maxlen);
|
||||||
@@ -215,73 +197,16 @@ pq_getstr(char *s, int maxlen)
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* USER FUNCTION - gets a newline-terminated string from the backend.
|
|
||||||
*
|
|
||||||
* Chiefly here so that applications can use "COPY <rel> to stdout"
|
|
||||||
* and read the output string. Returns a null-terminated string in s.
|
|
||||||
*
|
|
||||||
* PQgetline reads up to maxlen-1 characters (like fgets(3)) but strips
|
|
||||||
* the terminating \n (like gets(3)).
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* EOF if it is detected or invalid arguments are given
|
|
||||||
* 0 if EOL is reached (i.e., \n has been read)
|
|
||||||
* (this is required for backward-compatibility -- this
|
|
||||||
* routine used to always return EOF or 0, assuming that
|
|
||||||
* the line ended within maxlen bytes.)
|
|
||||||
* 1 in other cases
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
PQgetline(char *s, int maxlen)
|
|
||||||
{
|
|
||||||
if (!Pfin || !s || maxlen <= 1)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
if (fgets(s, maxlen - 1, Pfin) == NULL)
|
|
||||||
return feof(Pfin) ? EOF : 1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (; *s; s++)
|
|
||||||
{
|
|
||||||
if (*s == '\n')
|
|
||||||
{
|
|
||||||
*s = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* USER FUNCTION - sends a string to the backend.
|
|
||||||
*
|
|
||||||
* Chiefly here so that applications can use "COPY <rel> from stdin".
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* 0 in all cases.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
PQputline(char *s)
|
|
||||||
{
|
|
||||||
if (Pfout)
|
|
||||||
{
|
|
||||||
fputs(s, Pfout);
|
|
||||||
fflush(Pfout);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
* pq_getnchar - get n characters from connection
|
* pq_getnchar - get n characters from connection, and null terminate
|
||||||
* --------------------------------
|
* --------------------------------
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pq_getnchar(char *s, int off, int maxlen)
|
pq_getnchar(char *s, int off, int maxlen)
|
||||||
{
|
{
|
||||||
return pqGetNBytes(s + off, maxlen, Pfin);
|
int r = pqGetNBytes(s + off, maxlen);
|
||||||
|
s[off+maxlen] = '\0';
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
@@ -297,9 +222,6 @@ pq_getint(int b)
|
|||||||
int n,
|
int n,
|
||||||
status = 1;
|
status = 1;
|
||||||
|
|
||||||
if (!Pfin)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mjl: Seems inconsisten w/ return value of pq_putint (void). Also,
|
* mjl: Seems inconsisten w/ return value of pq_putint (void). Also,
|
||||||
* EOF is a valid return value for an int! XXX
|
* EOF is a valid return value for an int! XXX
|
||||||
@@ -308,13 +230,13 @@ pq_getint(int b)
|
|||||||
switch (b)
|
switch (b)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
status = ((n = fgetc(Pfin)) == EOF);
|
status = ((n = pq_getchar()) == EOF);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
status = pqGetShort(&n, Pfin);
|
status = pqGetShort(&n);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
status = pqGetLong(&n, Pfin);
|
status = pqGetLong(&n);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "** Unsupported size %d\n", b);
|
fprintf(stderr, "** Unsupported size %d\n", b);
|
||||||
@@ -343,9 +265,9 @@ pq_putstr(char *s)
|
|||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
|
|
||||||
p = pg_server_to_client(s, strlen(s));
|
p = pg_server_to_client(s, strlen(s));
|
||||||
if (pqPutString(p, Pfout))
|
if (pqPutString(p))
|
||||||
#else
|
#else
|
||||||
if (pqPutString(s, Pfout))
|
if (pqPutString(s))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
||||||
@@ -362,10 +284,10 @@ pq_putstr(char *s)
|
|||||||
void
|
void
|
||||||
pq_putnchar(char *s, int n)
|
pq_putnchar(char *s, int n)
|
||||||
{
|
{
|
||||||
if (pqPutNBytes(s, n, Pfout))
|
if (pqPutNBytes(s, n))
|
||||||
{
|
{
|
||||||
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
||||||
"FATAL: pq_putnchar: fputc() failed: errno=%d\n",
|
"FATAL: pq_putnchar: pqPutNBytes() failed: errno=%d\n",
|
||||||
errno);
|
errno);
|
||||||
fputs(PQerrormsg, stderr);
|
fputs(PQerrormsg, stderr);
|
||||||
pqdebug("%s", PQerrormsg);
|
pqdebug("%s", PQerrormsg);
|
||||||
@@ -384,20 +306,17 @@ pq_putint(int i, int b)
|
|||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!Pfout)
|
|
||||||
return;
|
|
||||||
|
|
||||||
status = 1;
|
status = 1;
|
||||||
switch (b)
|
switch (b)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
status = (fputc(i, Pfout) == EOF);
|
status = (pq_putchar(i) == EOF);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
status = pqPutShort(i, Pfout);
|
status = pqPutShort(i);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
status = pqPutLong(i, Pfout);
|
status = pqPutLong(i);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "** Unsupported size %d\n", b);
|
fprintf(stderr, "** Unsupported size %d\n", b);
|
||||||
@@ -485,6 +404,19 @@ pq_getinserv(struct sockaddr_in * sin, char *host, char *serv)
|
|||||||
* Stream functions are used for vanilla TCP connection protocol.
|
* Stream functions are used for vanilla TCP connection protocol.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static char sock_path[MAXPGPATH + 1] = "";
|
||||||
|
|
||||||
|
/* StreamDoUnlink()
|
||||||
|
* Shutdown routine for backend connection
|
||||||
|
* If a Unix socket is used for communication, explicitly close it.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
StreamDoUnlink()
|
||||||
|
{
|
||||||
|
Assert(sock_path[0]);
|
||||||
|
unlink(sock_path);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* StreamServerPort -- open a sock stream "listening" port.
|
* StreamServerPort -- open a sock stream "listening" port.
|
||||||
*
|
*
|
||||||
@@ -498,19 +430,6 @@ pq_getinserv(struct sockaddr_in * sin, char *host, char *serv)
|
|||||||
* RETURNS: STATUS_OK or STATUS_ERROR
|
* RETURNS: STATUS_OK or STATUS_ERROR
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char sock_path[MAXPGPATH + 1] = "";
|
|
||||||
|
|
||||||
/* do_unlink()
|
|
||||||
* Shutdown routine for backend connection
|
|
||||||
* If a Unix socket is used for communication, explicitly close it.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
StreamDoUnlink()
|
|
||||||
{
|
|
||||||
Assert(sock_path[0]);
|
|
||||||
unlink(sock_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
StreamServerPort(char *hostName, short portName, int *fdP)
|
StreamServerPort(char *hostName, short portName, int *fdP)
|
||||||
{
|
{
|
||||||
@@ -707,81 +626,6 @@ StreamClose(int sock)
|
|||||||
close(sock);
|
close(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------
|
|
||||||
* StreamOpen -- From client, initiate a connection with the
|
|
||||||
* server (Postmaster).
|
|
||||||
*
|
|
||||||
* RETURNS: STATUS_OK or STATUS_ERROR
|
|
||||||
*
|
|
||||||
* NOTE: connection is NOT established just because this
|
|
||||||
* routine exits. Local state is ok, but we haven't
|
|
||||||
* spoken to the postmaster yet.
|
|
||||||
* ---------------------------
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
StreamOpen(char *hostName, short portName, Port *port)
|
|
||||||
{
|
|
||||||
SOCKET_SIZE_TYPE len;
|
|
||||||
int err;
|
|
||||||
struct hostent *hp;
|
|
||||||
extern int errno;
|
|
||||||
|
|
||||||
/* set up the server (remote) address */
|
|
||||||
MemSet((char *) &port->raddr, 0, sizeof(port->raddr));
|
|
||||||
if (hostName)
|
|
||||||
{
|
|
||||||
if (!(hp = gethostbyname(hostName)) || hp->h_addrtype != AF_INET)
|
|
||||||
{
|
|
||||||
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
|
||||||
"FATAL: StreamOpen: unknown hostname: %s\n", hostName);
|
|
||||||
fputs(PQerrormsg, stderr);
|
|
||||||
pqdebug("%s", PQerrormsg);
|
|
||||||
return STATUS_ERROR;
|
|
||||||
}
|
|
||||||
memmove((char *) &(port->raddr.in.sin_addr),
|
|
||||||
(char *) hp->h_addr,
|
|
||||||
hp->h_length);
|
|
||||||
port->raddr.in.sin_family = AF_INET;
|
|
||||||
port->raddr.in.sin_port = htons(portName);
|
|
||||||
len = sizeof(struct sockaddr_in);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
port->raddr.un.sun_family = AF_UNIX;
|
|
||||||
len = UNIXSOCK_PATH(port->raddr.un, portName);
|
|
||||||
}
|
|
||||||
/* connect to the server */
|
|
||||||
if ((port->sock = socket(port->raddr.sa.sa_family, SOCK_STREAM, 0)) < 0)
|
|
||||||
{
|
|
||||||
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
|
||||||
"FATAL: StreamOpen: socket() failed: errno=%d\n", errno);
|
|
||||||
fputs(PQerrormsg, stderr);
|
|
||||||
pqdebug("%s", PQerrormsg);
|
|
||||||
return STATUS_ERROR;
|
|
||||||
}
|
|
||||||
err = connect(port->sock, &port->raddr.sa, len);
|
|
||||||
if (err < 0)
|
|
||||||
{
|
|
||||||
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
|
||||||
"FATAL: StreamOpen: connect() failed: errno=%d\n", errno);
|
|
||||||
fputs(PQerrormsg, stderr);
|
|
||||||
pqdebug("%s", PQerrormsg);
|
|
||||||
return STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* fill in the client address */
|
|
||||||
if (getsockname(port->sock, &port->laddr.sa, &len) < 0)
|
|
||||||
{
|
|
||||||
snprintf(PQerrormsg, ERROR_MSG_LENGTH,
|
|
||||||
"FATAL: StreamOpen: getsockname() failed: errno=%d\n", errno);
|
|
||||||
fputs(PQerrormsg, stderr);
|
|
||||||
pqdebug("%s", PQerrormsg);
|
|
||||||
return STATUS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MULTIBYTE
|
#ifdef MULTIBYTE
|
||||||
void
|
void
|
||||||
pq_putncharlen(char *s, int n)
|
pq_putncharlen(char *s, int n)
|
||||||
@@ -798,3 +642,24 @@ pq_putncharlen(char *s, int n)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Act like the stdio putc() function. Write one character
|
||||||
|
* to the stream. Return this character, or EOF on error.
|
||||||
|
*/
|
||||||
|
int pq_putchar(char c)
|
||||||
|
{
|
||||||
|
char isDone = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (send(MyProcPort->sock, &c, 1, 0) != 1) {
|
||||||
|
if (errno != EINTR)
|
||||||
|
return EOF; /* Anything other than interrupt is error! */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
isDone = 1; /* Done if we sent one char */
|
||||||
|
} while (!isDone);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -4,7 +4,9 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
#include "miscadmin.h"
|
||||||
#include "libpq/pqcomm.h"
|
#include "libpq/pqcomm.h"
|
||||||
|
#include "libpq/libpq.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -69,7 +71,7 @@
|
|||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
int
|
int
|
||||||
pqPutShort(int integer, FILE *f)
|
pqPutShort(int integer)
|
||||||
{
|
{
|
||||||
uint16 n;
|
uint16 n;
|
||||||
|
|
||||||
@@ -79,15 +81,12 @@ pqPutShort(int integer, FILE *f)
|
|||||||
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_s(integer) : htons((uint16) integer));
|
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_s(integer) : htons((uint16) integer));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fwrite(&n, 2, 1, f) != 1)
|
return pqPutNBytes((char *)&n, 2); /* 0 on success, EOF otherwise */
|
||||||
return EOF;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
int
|
int
|
||||||
pqPutLong(int integer, FILE *f)
|
pqPutLong(int integer)
|
||||||
{
|
{
|
||||||
uint32 n;
|
uint32 n;
|
||||||
|
|
||||||
@@ -97,20 +96,17 @@ pqPutLong(int integer, FILE *f)
|
|||||||
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_l(integer) : htonl((uint32) integer));
|
n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_l(integer) : htonl((uint32) integer));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fwrite(&n, 4, 1, f) != 1)
|
return pqPutNBytes((char *)&n,4);
|
||||||
return EOF;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
int
|
int
|
||||||
pqGetShort(int *result, FILE *f)
|
pqGetShort(int *result)
|
||||||
{
|
{
|
||||||
uint16 n;
|
uint16 n;
|
||||||
|
|
||||||
if (fread(&n, 2, 1, f) != 1)
|
if (pqGetNBytes((char *)&n,2) != 0)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
||||||
#ifdef FRONTEND
|
#ifdef FRONTEND
|
||||||
*result = (int) ntohs(n);
|
*result = (int) ntohs(n);
|
||||||
@@ -123,12 +119,12 @@ pqGetShort(int *result, FILE *f)
|
|||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
int
|
int
|
||||||
pqGetLong(int *result, FILE *f)
|
pqGetLong(int *result)
|
||||||
{
|
{
|
||||||
uint32 n;
|
uint32 n;
|
||||||
|
|
||||||
if (fread(&n, 4, 1, f) != 1)
|
if (pqGetNBytes((char *)&n, 4) != 0)
|
||||||
return EOF;
|
return EOF;
|
||||||
|
|
||||||
#ifdef FRONTEND
|
#ifdef FRONTEND
|
||||||
*result = (int) ntohl(n);
|
*result = (int) ntohl(n);
|
||||||
@@ -145,47 +141,59 @@ pqGetLong(int *result, FILE *f)
|
|||||||
Return 0 if ok.
|
Return 0 if ok.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
pqGetNBytes(char *s, size_t len, FILE *f)
|
pqGetNBytes(char *s, size_t len)
|
||||||
{
|
{
|
||||||
int cnt;
|
int bytesDone = 0;
|
||||||
|
|
||||||
if (f == NULL)
|
do {
|
||||||
return EOF;
|
int r = recv(MyProcPort->sock, s+bytesDone, len-bytesDone, MSG_WAITALL);
|
||||||
|
if (r == 0 || r == -1) {
|
||||||
|
if (errno != EINTR)
|
||||||
|
return EOF; /* All other than signal-interrupted is error */
|
||||||
|
continue; /* Otherwise, try again */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* r contains number of bytes received */
|
||||||
|
bytesDone += r;
|
||||||
|
|
||||||
cnt = fread(s, 1, len, f);
|
} while (bytesDone < len);
|
||||||
s[cnt] = '\0';
|
/* Zero-termination now in pq_getnchar() instead */
|
||||||
|
return 0;
|
||||||
return (cnt == len) ? 0 : EOF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
int
|
int
|
||||||
pqPutNBytes(const char *s, size_t len, FILE *f)
|
pqPutNBytes(const char *s, size_t len)
|
||||||
{
|
{
|
||||||
if (f == NULL)
|
int bytesDone = 0;
|
||||||
return EOF;
|
|
||||||
|
|
||||||
if (fwrite(s, 1, len, f) != len)
|
do {
|
||||||
return EOF;
|
int r = send(MyProcPort->sock, s+bytesDone, len-bytesDone, 0);
|
||||||
|
if (r == 0 || r == -1) {
|
||||||
|
if (errno != EINTR)
|
||||||
|
return EOF; /* Only signal interruption allowed */
|
||||||
|
continue; /* If interruped and read nothing, just try again */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* r contains number of bytes sent so far */
|
||||||
|
bytesDone += r;
|
||||||
|
} while (bytesDone < len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
int
|
int
|
||||||
pqGetString(char *s, size_t len, FILE *f)
|
pqGetString(char *s, size_t len)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if (f == NULL)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Keep on reading until we get the terminating '\0' and discard those
|
* Keep on reading until we get the terminating '\0' and discard those
|
||||||
* bytes we don't have room for.
|
* bytes we don't have room for.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while ((c = getc(f)) != EOF && c != '\0')
|
while ((c = pq_getchar()) != EOF && c != '\0')
|
||||||
if (len > 1)
|
if (len > 1)
|
||||||
{
|
{
|
||||||
*s++ = c;
|
*s++ = c;
|
||||||
@@ -202,33 +210,8 @@ pqGetString(char *s, size_t len, FILE *f)
|
|||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------- */
|
||||||
int
|
int
|
||||||
pqPutString(const char *s, FILE *f)
|
pqPutString(const char *s)
|
||||||
{
|
{
|
||||||
if (f == NULL)
|
return pqPutNBytes(s,strlen(s)+1);
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (fputs(s, f) == EOF)
|
|
||||||
return EOF;
|
|
||||||
|
|
||||||
fputc('\0', f); /* important to send an ending \0 since
|
|
||||||
* backend expects it */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
int
|
|
||||||
pqGetByte(FILE *f)
|
|
||||||
{
|
|
||||||
return getc(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- */
|
|
||||||
int
|
|
||||||
pqPutByte(int c, FILE *f)
|
|
||||||
{
|
|
||||||
if (!f)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (putc(c, f) == c) ? 0 : EOF;
|
|
||||||
}
|
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: libpq.h,v 1.22 1999/01/11 03:56:11 scrappy Exp $
|
* $Id: libpq.h,v 1.23 1999/01/12 12:49:52 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@@ -262,6 +262,7 @@ extern int pq_getchar(void);
|
|||||||
extern int pq_peekchar(void);
|
extern int pq_peekchar(void);
|
||||||
extern int pq_getnchar(char *s, int off, int maxlen);
|
extern int pq_getnchar(char *s, int off, int maxlen);
|
||||||
extern int pq_getint(int b);
|
extern int pq_getint(int b);
|
||||||
|
extern int pq_putchar(char c);
|
||||||
extern void pq_putstr(char *s);
|
extern void pq_putstr(char *s);
|
||||||
extern void pq_putnchar(char *s, int n);
|
extern void pq_putnchar(char *s, int n);
|
||||||
extern void pq_putint(int i, int b);
|
extern void pq_putint(int i, int b);
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 1994, Regents of the University of California
|
* Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: pqcomm.h,v 1.29 1998/09/01 04:36:31 momjian Exp $
|
* $Id: pqcomm.h,v 1.30 1999/01/12 12:49:52 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@@ -152,7 +152,7 @@ typedef struct CancelRequestPacket
|
|||||||
} CancelRequestPacket;
|
} CancelRequestPacket;
|
||||||
|
|
||||||
|
|
||||||
/* in pqcompriv.c */
|
/* in pqcomprim.c */
|
||||||
int pqGetShort(int *, FILE *);
|
int pqGetShort(int *, FILE *);
|
||||||
int pqGetLong(int *, FILE *);
|
int pqGetLong(int *, FILE *);
|
||||||
int pqGetNBytes(char *, size_t, FILE *);
|
int pqGetNBytes(char *, size_t, FILE *);
|
||||||
|
Reference in New Issue
Block a user