INTERFACEPQcomm ; FROM Ctypes IMPORT int, char; FROM Postgres IMPORT NAMEDATALEN; TYPE bool = int;
* startup msg parameters: path length, argument string length
CONST PATH_SIZE = 64;
CONST ARGV_SIZE = 64;
TYPE MsgType = {
ACK_MSG, (* acknowledge a message *)
ERROR_MSG, (* error response to client from server *)
RESET_MSG, (* client must reset connection *)
PRINT_MSG, (* tuples for client from server *)
NET_ERROR, (* error in net system call *)
FUNCTION, (* fastpath call (unused) *)
QUERY_MSG, (* client query to server *)
STARTUP_MSG, (* initialize a connection with a backend *)
DUPLICATE_MSG, (* duplicate msg arrived (errors msg only) *)
INVALID_MSG, (* for some control functions *)
STARTUP_KRB4_MSG, (* krb4 session follows startup packet *)
STARTUP_KRB5_MS (* krb5 session follows startup packet *)
(* insert new values here -- DO NOT REORDER OR DELETE ENTRIES *)
};
TYPE
Addr = ADDRESS;
PacketLen = int;
TYPE StartupInfo = RECORD
database: ARRAY [0..PATH_SIZE-1] OF char; (* database name *)
user: ARRAY [0..NAMEDATALEN-1] OF char; (* user name *)
options: ARRAY [0..ARGV_SIZE-1] OF char; (* possible additional args *)
execFile: ARRAY [0..ARGV_SIZE-1] OF char; (* possible backend to use *)
tty: ARRAY [0..PATH_SIZE-1] OF char; (* possible tty for debug output*)
END;
StartupInfo_star = UNTRACED REF StartupInfo;
amount of available data in a packet buffer
CONST MESSAGE_SIZE = BYTESIZE(StartupInfo) + 5;I/O can be blocking or non-blocking
CONST BLOCKING = 0; CONST NON_BLOCKING = 1;a PacketBuf gets shipped from client to server so be careful of differences in representation. Be sure to use htonl() and ntohl() on the len and msgtype fields!
TYPE
PacketBuf = RECORD
len: int;
msgtype: MsgType;
data: ARRAY [0..MESSAGE_SIZE-1] OF char;
END;
PacketBuf_star = UNTRACED REF PacketBuf;
update the conversion routines
StartupInfo2PacketBuf() and PacketBuf2StartupInfo() (decl. below)
if StartupInfo or PacketBuf structs ever change
* socket descriptor port * we need addresses of both sides to do authentication calls
TYPE
Port = RECORD
sock: int; (* file descriptor *)
mask: int; (* select mask *)
nBytes: int; (* nBytes read in so far *)
laddr: ADDRESS; (* sockaddr_in *)
raddr: ADDRESS; (* sockaddr_in *)
id: PacketBufId; (* id of packet buf currently in use
*)
buf: PacketBuf; (* stream implementation (curr pack buf) *)
END;
Port_star = UNTRACED REF Port;
invalid socket descriptor
CONST INVALID_SOCK = (-1); CONST INVALID_ID = (-1); MAX_CONNECTIONS = 10; N_PACK_BUFS = 20;no multi-packet messages yet
CONST MAX_PACKET_BACKLOG = 1; CONST DEFAULT_STRING = ""; <*EXTERNAL*> VAR Pfout, Pfin: FILE; PQAsyncNotifyWaiting: int; TYPE FILE = ADDRESS;
* prototypes for functions in pqpacket.c
<*EXTERNAL*>PROCEDURE PacketReceive(port: Port_star;
buf: PacketBuf_star;
nonBlocking: bool): int;
<*EXTERNAL*>PROCEDURE PacketSend(port: Port_star;
buf: PacketBuf_star;
len: PacketLen;
nonBlocking: bool): int;
<*EXTERNAL*>PROCEDURE StartupInfo2PacketBuf(startup: StartupInfo_star): PacketBuf_star;
<*EXTERNAL*>PROCEDURE PacketBuf2StartupInfo(pkt: PacketBuf_star): PacketBuf_star;
END PQcomm.