/* Mark message as done */
conn->inStart = newInStart;
}
/* *pqPutMsgStart:beginconstructionofamessagetotheserver * *msg_typeisthemessagetypebyte,or0foramessagewithouttypebyte *(onlystartupmessageshavenotypebyte) * *Returns0onsuccess,EOFonerror * *Theideahereisthatweconstructthemessageinconn->outBuffer, *beginningjustpastanydataalreadyinoutBuffer(ie,at *outBuffer+outCount).Weenlargethebufferasneededtoholdthemessage. *Whenthemessageiscomplete,wefillinthelengthword(ifneeded)and *thenadvanceoutCountpastthemessage,makingiteligibletosend. * *Thestatevariableconn->outMsgStartpointstotheincompletemessage's *lengthword:itiseitheroutCountoroutCount+1dependingonwhether *thereisatypebyte.Thestatevariableconn->outMsgEndistheendof *thedatacollectedsofar.
*/ int
pqPutMsgStart(char msg_type, PGconn *conn)
{ int lenPos; int endPos;
/* allow room for message type byte */ if (msg_type)
endPos = conn->outCount + 1; else
endPos = conn->outCount;
/* do we want a length word? */
lenPos = endPos; /* allow room for message length */
endPos += 4;
/* make sure there is room for message header */ if (pqCheckOutBufferSpace(endPos, conn)) return EOF; /* okay, save the message type byte if any */ if (msg_type)
conn->outBuffer[conn->outCount] = msg_type; /* set up the message pointers */
conn->outMsgStart = lenPos;
conn->outMsgEnd = endPos; /* length word, if needed, will be filled in by pqPutMsgEnd */
return0;
}
/* *pqPutMsgBytes:addbytestoapartially-constructedmessage * *Returns0onsuccess,EOFonerror
*/ staticint
pqPutMsgBytes(constvoid *buf, size_t len, PGconn *conn)
{ /* make sure there is room for it */ if (pqCheckOutBufferSpace(conn->outMsgEnd + len, conn)) return EOF; /* okay, save the data */
memcpy(conn->outBuffer + conn->outMsgEnd, buf, len);
conn->outMsgEnd += len; /* no Pfdebug call here, caller should do it */ return0;
}
/* *pqPutMsgEnd:finishconstructingamessageandpossiblysendit * *Returns0onsuccess,EOFonerror * *Wedon'tactuallysendanythinghereunlesswe'veaccumulatedatleast *8Kworthofdata(thetypicalsizeofapipebufferonUnixsystems). *Thisavoidssendingsmallpartialpackets.ThecallermustusepqFlush *whenit'simportanttoflushallthedataouttotheserver.
*/ int
pqPutMsgEnd(PGconn *conn)
{ /* Fill in length word if needed */ if (conn->outMsgStart >= 0)
{
uint32 msgLen = conn->outMsgEnd - conn->outMsgStart;
if (pqSendSome(conn, toSend) < 0) return EOF; /* in nonblock mode, don't complain if unable to send it all */
}
return0;
}
/* ---------- *pqReadData:readmoredata,ifanyisavailable *Possiblereturnvalues: *1:successfullyloadedatleastonemorebyte *0:nodataispresentlyavailable,butnoerrordetected *-1:errordetected(includingEOF=connectionclosure); *conn->errorMessageset *NOTE:callersmustnotassumethatpointersorindexesintoconn->inBuffer *remainvalidacrossthiscall! *----------
*/ int
pqReadData(PGconn *conn)
{ int someread = 0; int nread;
if (conn->sock == PGINVALID_SOCKET)
{
libpq_append_conn_error(conn, "connection not open"); return -1;
}
/* Left-justify any data in the buffer to make room */ if (conn->inStart < conn->inEnd)
{ if (conn->inStart > 0)
{
memmove(conn->inBuffer, conn->inBuffer + conn->inStart,
conn->inEnd - conn->inStart);
conn->inEnd -= conn->inStart;
conn->inCursor -= conn->inStart;
conn->inStart = 0;
}
} else
{ /* buffer is logically empty, reset it */
conn->inStart = conn->inCursor = conn->inEnd = 0;
}
/* *Ifthebufferisfairlyfull,enlargeit.Weneedtobeabletoenlarge *thebufferincaseasinglemessageexceedstheinitialbuffersize.We *enlargebeforefillingthebufferentirelysoastoavoidaskingthe *kernelforapartialpacket.Themagicconstanthereshouldbelarge *enoughforaTCPpacketorUnixpipebufferload.8Kistheusualpipe *buffersize,so...
*/ if (conn->inBufSize - conn->inEnd < 8192)
{ if (pqCheckInBufferSpace(conn->inEnd + (size_t) 8192, conn))
{ /* *Wedon'tinsistthattheenlargeworked,butweneedsomeroom
*/ if (conn->inBufSize - conn->inEnd < 100) return -1; /* errorMessage already set */
}
}
/* OK, try to read some data */
retry3:
nread = pqsecure_read(conn, conn->inBuffer + conn->inEnd,
conn->inBufSize - conn->inEnd); if (nread < 0)
{ switch (SOCK_ERRNO)
{ case EINTR: goto retry3;
/* Some systems return EAGAIN/EWOULDBLOCK for no data */ #ifdef EAGAIN case EAGAIN: return someread; #endif #ifdefined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) case EWOULDBLOCK: return someread; #endif
/* We might get ECONNRESET etc here if connection failed */ case ALL_CONNECTION_FAILURE_ERRNOS: goto definitelyFailed;
default: /* pqsecure_read set the error message for us */ return -1;
}
} if (nread > 0)
{
conn->inEnd += nread;
#ifdef USE_SSL if (conn->ssl_in_use) return0; #endif
switch (pqReadReady(conn))
{ case0: /* definitely no data available */ return0; case1: /* ready for read */ break; default: /* we override pqReadReady's message with something more useful */ goto definitelyEOF;
}
/* Some systems return EAGAIN/EWOULDBLOCK for no data */ #ifdef EAGAIN case EAGAIN: return0; #endif #ifdefined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN)) case EWOULDBLOCK: return0; #endif
/* We might get ECONNRESET etc here if connection failed */ case ALL_CONNECTION_FAILURE_ERRNOS: goto definitelyFailed;
default: /* pqsecure_read set the error message for us */ return -1;
}
} if (nread > 0)
{
conn->inEnd += nread; return1;
}
/* *OK,wearegettingazeroreadeventhoughselect()saysready.This *meanstheconnectionhasbeenclosed.Cope.
*/
definitelyEOF:
libpq_append_conn_error(conn, "server closed the connection unexpectedly\n" "\tThis probably means the server terminated abnormally\n" "\tbefore or while processing the request.");
/* Come here if lower-level code already set a suitable errorMessage */
definitelyFailed: /* Do *not* drop any already-read data; caller still wants it */
pqDropConnection(conn, false);
conn->status = CONNECTION_BAD; /* No more connection to backend */ return -1;
}
/* *pqSendSome:senddatawaitingintheoutputbuffer. * *lenishowmuchtotrytosend(typicallyequaltooutCount,butmay *beless). * *Return0onsuccess,-1onfailureand1whennotalldatacouldbesent *becausethesocketwouldblockandtheconnectionisnon-blocking. * *Notethatthisisalsoresponsibleforconsumingdatafromthesocket *(puttingitinconn->inBuffer)inanysituationwherewecan'tsend *allthespecifieddataimmediately. * *Ifasocket-levelwritefailureoccurs,conn->write_failedissetandthe *errormessageissavedinconn->write_err_msg,butwecleartheoutput *bufferandreturnzeroanyway;thisisbecausecallersshouldsoldieron *untilwehavereadwhatwecanfromtheserverandcheckedforanerror *message.write_err_msgshouldbereportedonlywhenweareunableto *obtainaservererrorfirst.Muchofthatbehaviorisimplementedat *lowerlevels,butthisfunctiondealswithsomeedgecases.
*/ staticint
pqSendSome(PGconn *conn, int len)
{ char *ptr = conn->outBuffer; int remaining = conn->outCount; int result = 0;
/* *Ifwealreadyhadawritefailure,wewillneveragaintrytosenddata *onthatconnection.Evenifthekernelwouldletus,we'veprobably *lostmessageboundarysyncwiththeserver.conn->write_failed *thereforepersistsuntiltheconnectionisreset,andwejustdiscard *alldatapresentedtobewritten.However,aslongaswestillhavea *validsocket,weshouldcontinuetoabsorbdatafromthebackend,so *thatwecancollectanyfinalerrormessages.
*/ if (conn->write_failed)
{ /* conn->write_err_msg should be set up already */
conn->outCount = 0; /* Absorb input data if any, and detect socket closure */ if (conn->sock != PGINVALID_SOCKET)
{ if (pqReadData(conn) < 0) return -1;
} return0;
}
if (conn->sock == PGINVALID_SOCKET)
{
conn->write_failed = true; /* Store error message in conn->write_err_msg, if possible */ /* (strdup failure is OK, we'll cope later) */
conn->write_err_msg = strdup(libpq_gettext("connection not open\n")); /* Discard queued data; no chance it'll ever be sent */
conn->outCount = 0; return0;
}
/* while there's still data to send */ while (len > 0)
{ int sent;
#ifndef WIN32
sent = pqsecure_write(conn, ptr, len); #else
if (!already_bound)
{ /* bindtextdomain() does not preserve errno */ #ifdef WIN32 int save_errno = GetLastError(); #else int save_errno = errno; #endif
if (PQExpBufferBroken(errorMessage)) return; /* already failed */
/* Loop in case we have to retry after enlarging the buffer. */ do
{
errno = save_errno;
va_start(args, fmt);
done = appendPQExpBufferVA(errorMessage, libpq_gettext(fmt), args);
va_end(args);
} while (!done);
if (PQExpBufferBroken(&conn->errorMessage)) return; /* already failed */
/* Loop in case we have to retry after enlarging the buffer. */ do
{
errno = save_errno;
va_start(args, fmt);
done = appendPQExpBufferVA(&conn->errorMessage, libpq_gettext(fmt), args);
va_end(args);
} while (!done);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.36 Sekunden
(vorverarbeitet am 2026-08-06)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.