om: "Martin J. Laubach" <mjl@CSlab.tuwien.ac.at>
Subject: [HACKERS] Patch for io routines I am currently trying to improve on the front-backend communication routines; and noticed that lots of code are duplicated for libpq and the backend. This is a first patch that tries to share code between the two, more to follow. mjl
This commit is contained in:
parent
a9049a4a28
commit
ea58f28ee8
|
@ -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.8 1997/03/12 21:22:19 scrappy Exp $
|
* $Id: pqcomm.h,v 1.9 1997/03/16 18:50:47 scrappy Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Some of this should move to libpq.h
|
* Some of this should move to libpq.h
|
||||||
|
@ -123,6 +123,11 @@ typedef struct Port {
|
||||||
extern FILE *Pfout, *Pfin;
|
extern FILE *Pfout, *Pfin;
|
||||||
extern int PQAsyncNotifyWaiting;
|
extern int PQAsyncNotifyWaiting;
|
||||||
|
|
||||||
|
/* in pqcompriv.c */
|
||||||
|
int pqGetShort(int *, FILE *);
|
||||||
|
int pqGetLong(int *, FILE *);
|
||||||
|
int pqPutShort(int, FILE *);
|
||||||
|
int pqPutLong(int, FILE *);
|
||||||
/*
|
/*
|
||||||
* prototypes for functions in pqpacket.c
|
* prototypes for functions in pqpacket.c
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.29 1997/03/15 19:17:03 scrappy Exp $
|
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.30 1997/03/16 18:51:13 scrappy Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ CFLAGS+= $(KRBFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-lobj.o \
|
OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-lobj.o \
|
||||||
dllist.o pqsignal.o
|
dllist.o pqsignal.o pqcomprim.o
|
||||||
|
|
||||||
# Shared library stuff
|
# Shared library stuff
|
||||||
shlib :=
|
shlib :=
|
||||||
|
@ -58,7 +58,10 @@ fe-lobj.o: ../backend/fmgr.h
|
||||||
# We need to compile this with special options for shared libs,
|
# We need to compile this with special options for shared libs,
|
||||||
# so we can't use the object in ../backend
|
# so we can't use the object in ../backend
|
||||||
dllist.c: ../backend/lib/dllist.c
|
dllist.c: ../backend/lib/dllist.c
|
||||||
-ln ../backend/lib/dllist.c
|
-ln -s ../backend/lib/dllist.c
|
||||||
|
|
||||||
|
pqcomprim.c: ../backend/libpq/pqcomprim.c
|
||||||
|
-ln -s ../backend/libpq/pqcomprim.c
|
||||||
|
|
||||||
# The following rules cause dependencies in the backend directory to
|
# The following rules cause dependencies in the backend directory to
|
||||||
# get made if they don't exist, but don't cause them to get remade if they
|
# get made if they don't exist, but don't cause them to get remade if they
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.4 1996/12/31 07:29:17 bryanh Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.5 1997/03/16 18:51:29 scrappy Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -23,76 +23,73 @@
|
||||||
|
|
||||||
#include "libpq-fe.h"
|
#include "libpq-fe.h"
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
/* pqGetc:
|
/* pqGetc:
|
||||||
get a character from stream f
|
get a character from stream f
|
||||||
|
|
||||||
if debug is set, also echo the character fetched
|
if debug is set, also echo the character fetched
|
||||||
*/
|
*/
|
||||||
int
|
int pqGetc(FILE* fin, FILE* debug)
|
||||||
pqGetc(FILE* fin, FILE* debug)
|
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
c = getc(fin);
|
c = getc(fin);
|
||||||
|
|
||||||
if (debug && c != EOF)
|
if (debug && c != EOF)
|
||||||
fprintf(debug, "From backend> %c\n", c);
|
fprintf(debug, "From backend> %c\n", c);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
/* pqPutnchar:
|
/* pqPutnchar:
|
||||||
send a string of exactly len length into stream f
|
send a string of exactly len length into stream f
|
||||||
|
|
||||||
returns 1 if there was an error, 0 otherwise.
|
returns 1 if there was an error, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
int
|
int pqPutnchar(const char* s, int len, FILE *f, FILE *debug)
|
||||||
pqPutnchar(const char* s, int len, FILE *f, FILE *debug)
|
|
||||||
{
|
{
|
||||||
int status;
|
|
||||||
|
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (debug) fputs("To backend>", debug);
|
|
||||||
while (len--) {
|
|
||||||
status = fputc(*s,f);
|
|
||||||
if(debug)
|
if(debug)
|
||||||
fputc(*s,debug);
|
fprintf(debug, "To backend> %s\n", s);
|
||||||
s++;
|
|
||||||
if (status == EOF)
|
if(fwrite(s, 1, len, f) != len)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
if (debug) fputc('\n', debug);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
/* pqGetnchar:
|
/* pqGetnchar:
|
||||||
get a string of exactly len length from stream f
|
get a string of exactly len length from stream f
|
||||||
*/
|
*/
|
||||||
int
|
int pqGetnchar(char* s, int len, FILE *f, FILE *debug)
|
||||||
pqGetnchar(char* s, int len, FILE *f, FILE *debug)
|
|
||||||
{
|
{
|
||||||
int c;
|
int cnt;
|
||||||
|
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
while (len-- && (c = getc(f)) != EOF)
|
cnt = fread(s, 1, len, f);
|
||||||
*s++ = c;
|
s[cnt] = '\0';
|
||||||
*s = '\0';
|
/* mjl: actually needs up to len+1 bytes, is this okay? XXX */
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
fprintf(debug, "From backend (%d)> %s\n", len, s);
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
fprintf(debug, "From backend> %s\n", s);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
/* pqGets:
|
/* pqGets:
|
||||||
get a string of up to length len from stream f
|
get a string of up to length len from stream f
|
||||||
*/
|
*/
|
||||||
int
|
int pqGets(char* s, int len, FILE *f, FILE *debug)
|
||||||
pqGets(char* s, int len, FILE *f, FILE *debug)
|
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
const char *str = s;
|
||||||
|
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -100,80 +97,73 @@ pqGets(char* s, int len, FILE *f, FILE *debug)
|
||||||
while (len-- && (c = getc(f)) != EOF && c)
|
while (len-- && (c = getc(f)) != EOF && c)
|
||||||
*s++ = c;
|
*s++ = c;
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
|
/* mjl: actually needs up to len+1 bytes, is this okay? XXX */
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
fprintf(debug, "From backend> \"%s\"\n", str);
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
fprintf(debug, "From backend> %s\n", s);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
/* pgPutInt
|
/* pgPutInt
|
||||||
send an integer of up to 4 bytesto the file stream
|
send an integer of 2 or 4 bytes to the file stream, compensate
|
||||||
do this one byte at at time.
|
for host endianness.
|
||||||
This insures that machines with different ENDIANness can talk to each other
|
|
||||||
get a n-byte integer from the stream into result
|
|
||||||
returns 0 if successful, 1 otherwise
|
returns 0 if successful, 1 otherwise
|
||||||
*/
|
*/
|
||||||
int
|
int pqPutInt(const int integer, int bytes, FILE* f, FILE *debug)
|
||||||
pqPutInt(const int integer, int bytes, FILE* f, FILE *debug)
|
|
||||||
{
|
{
|
||||||
int i;
|
int retval = 0;
|
||||||
int status;
|
|
||||||
|
|
||||||
i = integer;
|
switch(bytes)
|
||||||
|
{
|
||||||
if (bytes > 4)
|
case 2:
|
||||||
bytes = 4;
|
retval = pqPutShort(integer, f);
|
||||||
|
break;
|
||||||
while (bytes--) {
|
case 4:
|
||||||
status = fputc(i & 0xff, f);
|
retval = pqPutLong(integer, f);
|
||||||
i >>= 8;
|
break;
|
||||||
if (status == EOF) {
|
default:
|
||||||
return 1;
|
fprintf(stderr, "** int size %d not supported\n", bytes);
|
||||||
}
|
retval = 1;
|
||||||
}
|
|
||||||
if (debug) fprintf(debug, "To backend (#)> %d\n", integer);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (debug) fprintf(debug, "To backend (%d#)> %d\n", bytes, integer);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
/* pgGetInt
|
/* pgGetInt
|
||||||
reconstructs the integer one byte at a time.
|
read a 2 or 4 byte integer from the stream and swab it around
|
||||||
This insures that machines with different ENDIANness can talk to each other
|
to compensate for different endianness
|
||||||
get a n-byte integer from the stream into result
|
|
||||||
returns 0 if successful
|
returns 0 if successful
|
||||||
*/
|
*/
|
||||||
int
|
int pqGetInt(int* result, int bytes, FILE* f, FILE *debug)
|
||||||
pqGetInt(int* result, int bytes, FILE* f, FILE *debug)
|
|
||||||
{
|
{
|
||||||
int c;
|
int retval = 0;
|
||||||
int p;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
if (f == NULL)
|
switch(bytes)
|
||||||
return 1;
|
|
||||||
|
|
||||||
p = 0;
|
|
||||||
n = 0;
|
|
||||||
while (bytes && (c = getc(f)) != EOF)
|
|
||||||
{
|
{
|
||||||
n |= (c & 0xff) << p;
|
case 2:
|
||||||
p += 8;
|
retval = pqGetShort(result, f);
|
||||||
bytes--;
|
break;
|
||||||
|
case 4:
|
||||||
|
retval = pqGetLong(result, f);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "** int size %d not supported\n", bytes);
|
||||||
|
retval = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes != 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
*result = n;
|
|
||||||
if (debug)
|
if (debug)
|
||||||
fprintf(debug,"From backend (#)> %d\n",*result);
|
fprintf(debug,"From backend (#%d)> %d\n", bytes, *result);
|
||||||
return 0;
|
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
int
|
int pqPuts(const char* s, FILE *f, FILE *debug)
|
||||||
pqPuts(const char* s, FILE *f, FILE *debug)
|
|
||||||
{
|
{
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -181,23 +171,24 @@ pqPuts(const char* s, FILE *f, FILE *debug)
|
||||||
if (fputs(s, f) == EOF)
|
if (fputs(s, f) == EOF)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
fputc('\0',f); /* important to send an ending EOF since backend expects it */
|
fputc('\0', f); /* important to send an ending \0 since backend expects it */
|
||||||
fflush(f);
|
fflush(f);
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
fprintf(debug, "To backend> %s\n", s);
|
fprintf(debug, "To backend> %s\n", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
void
|
void pqFlush(FILE *f, FILE *debug)
|
||||||
pqFlush(FILE *f, FILE *debug)
|
|
||||||
{
|
{
|
||||||
if (f)
|
if (f)
|
||||||
fflush(f);
|
fflush(f);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
fflush(debug);
|
fflush(debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------- */
|
||||||
|
|
Loading…
Reference in New Issue