diff options
Diffstat (limited to 'src/backend/libpq/pqcomprim.c')
-rw-r--r-- | src/backend/libpq/pqcomprim.c | 160 |
1 files changed, 99 insertions, 61 deletions
diff --git a/src/backend/libpq/pqcomprim.c b/src/backend/libpq/pqcomprim.c index 53742190f3e..0dd46d9205a 100644 --- a/src/backend/libpq/pqcomprim.c +++ b/src/backend/libpq/pqcomprim.c @@ -1,122 +1,150 @@ #include <stdlib.h> #include <stdio.h> +#include <netinet/in.h> #include "postgres.h" #include "libpq/pqcomm.h" -#ifdef HAVE_ENDIAN_H -#include <endian.h> -#endif - -/* --------------------------------------------------------------------- */ -/* These definitions for ntoh/hton are the other way around from the - * default system definitions, so we roll our own here. +/* + * The backend supports the old little endian byte order and the current + * network byte order. */ +#ifndef FRONTEND + +#include "libpq/libpq-be.h" + +#ifdef HAVE_ENDIAN_H +#include <endian.h> +#endif + #ifndef BYTE_ORDER #error BYTE_ORDER must be defined as LITTLE_ENDIAN, BIG_ENDIAN or PDP_ENDIAN #endif #if BYTE_ORDER == LITTLE_ENDIAN -#define ntoh_s(n) n -#define ntoh_l(n) n -#define hton_s(n) n -#define hton_l(n) n -#else /* BYTE_ORDER != LITTLE_ENDIAN */ + +#define ntoh_s(n) n +#define ntoh_l(n) n +#define hton_s(n) n +#define hton_l(n) n + +#else #if BYTE_ORDER == BIG_ENDIAN -#define ntoh_s(n) (u_short)(((u_char *)&n)[1] << 8 \ - | ((u_char *)&n)[0]) -#define ntoh_l(n) (uint32) (((u_char *)&n)[3] << 24 \ - | ((u_char *)&n)[2] << 16 \ - | ((u_char *)&n)[1] << 8 \ - | ((u_char *)&n)[0]) -#define hton_s(n) (ntoh_s(n)) -#define hton_l(n) (ntoh_l(n)) + +#define ntoh_s(n) (uint16)(((u_char *)&n)[1] << 8 \ + | ((u_char *)&n)[0]) +#define ntoh_l(n) (uint32)(((u_char *)&n)[3] << 24 \ + | ((u_char *)&n)[2] << 16 \ + | ((u_char *)&n)[1] << 8 \ + | ((u_char *)&n)[0]) +#define hton_s(n) (ntoh_s(n)) +#define hton_l(n) (ntoh_l(n)) + #else -/* BYTE_ORDER != BIG_ENDIAN */ #if BYTE_ORDER == PDP_ENDIAN + #error PDP_ENDIAN macros not written yet + #else -/* BYTE_ORDER != anything known */ + #error BYTE_ORDER not defined as anything understood -#endif /* BYTE_ORDER == PDP_ENDIAN */ -#endif /* BYTE_ORDER == BIG_ENDIAN */ -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ + +#endif +#endif +#endif + +#endif + /* --------------------------------------------------------------------- */ int pqPutShort(int integer, FILE *f) { - int retval = 0; - u_short n, - s; + uint16 n; + +#ifdef FRONTEND + n = htons((uint16)integer); +#else + n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_s(integer) : htons((uint16)integer)); +#endif - s = integer; - n = hton_s(s); - if (fwrite(&n, sizeof(u_short), 1, f) != 1) - retval = EOF; + if (fwrite(&n, 2, 1, f) != 1) + return EOF; - return retval; + return 0; } /* --------------------------------------------------------------------- */ int pqPutLong(int integer, FILE *f) { - int retval = 0; - uint32 n; + uint32 n; - n = hton_l(integer); - if (fwrite(&n, sizeof(uint32), 1, f) != 1) - retval = EOF; +#ifdef FRONTEND + n = htonl((uint32)integer); +#else + n = ((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? hton_l(integer) : htonl((uint32)integer)); +#endif - return retval; + if (fwrite(&n, 4, 1, f) != 1) + return EOF; + + return 0; } /* --------------------------------------------------------------------- */ int pqGetShort(int *result, FILE *f) { - int retval = 0; - u_short n; + uint16 n; - if (fread(&n, sizeof(u_short), 1, f) != 1) - retval = EOF; + if (fread(&n, 2, 1, f) != 1) + return EOF; + +#ifdef FRONTEND + *result = (int)ntohs(n); +#else + *result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_s(n) : ntohs(n)); +#endif - *result = ntoh_s(n); - return retval; + return 0; } /* --------------------------------------------------------------------- */ int pqGetLong(int *result, FILE *f) { - int retval = 0; - uint32 n; + uint32 n; - if (fread(&n, sizeof(uint32), 1, f) != 1) - retval = EOF; + if (fread(&n, 4, 1, f) != 1) + return EOF; - *result = ntoh_l(n); - return retval; +#ifdef FRONTEND + *result = (int)ntohl(n); +#else + *result = (int)((PG_PROTOCOL_MAJOR(FrontendProtocol) == 0) ? ntoh_l(n) : ntohl(n)); +#endif + + return 0; } /* --------------------------------------------------------------------- */ -/* pqGetNBytes: Read a chunk of exactly len bytes in buffer s. +/* pqGetNBytes: Read a chunk of exactly len bytes in buffer s (which must be 1 + byte longer) and terminate it with a '\0'. Return 0 if ok. */ int pqGetNBytes(char *s, size_t len, FILE *f) { - int cnt; + int cnt; if (f == NULL) return EOF; cnt = fread(s, 1, len, f); s[cnt] = '\0'; - /* mjl: actually needs up to len+1 bytes, is this okay? XXX */ return (cnt == len) ? 0 : EOF; } @@ -126,7 +154,7 @@ int pqPutNBytes(const char *s, size_t len, FILE *f) { if (f == NULL) - return 0; + return EOF; if (fwrite(s, 1, len, f) != len) return EOF; @@ -138,15 +166,27 @@ pqPutNBytes(const char *s, size_t len, FILE *f) int pqGetString(char *s, size_t len, FILE *f) { - int c; + int c; if (f == NULL) return EOF; - while (len-- && (c = getc(f)) != EOF && c) - *s++ = c; + /* + * Keep on reading until we get the terminating '\0' and discard those + * bytes we don't have room for. + */ + + while ((c = getc(f)) != EOF && c != '\0') + if (len > 1) + { + *s++ = c; + len--; + } + *s = '\0'; - /* mjl: actually needs up to len+1 bytes, is this okay? XXX */ + + if (c == EOF) + return EOF; return 0; } @@ -183,5 +223,3 @@ pqPutByte(int c, FILE *f) return (putc(c, f) == c) ? 0 : EOF; } - -/* --------------------------------------------------------------------- */ |