4040
4141const XLogRecPtr InvalidXLogRecPtr = {0 ,0 };
4242
43+ /* fd for currently open WAL file */
44+ static int walfile = -1 ;
45+
46+
4347/*
4448 * Open a new WAL file in the specified directory. Store the name
4549 * (not including the full directory) in namebuf. Assumes there is
@@ -97,6 +101,7 @@ open_walfile(XLogRecPtr startpoint, uint32 timeline, char *basedir, char *namebu
97101{
98102fprintf (stderr ,_ ("%s: could not pad WAL segment %s: %s\n" ),
99103progname ,fn ,strerror (errno ));
104+ free (zerobuf );
100105close (f );
101106unlink (fn );
102107return -1 ;
@@ -121,7 +126,7 @@ open_walfile(XLogRecPtr startpoint, uint32 timeline, char *basedir, char *namebu
121126 * completed writing the whole segment.
122127 */
123128static bool
124- close_walfile (int walfile , char * basedir ,char * walname ,bool segment_complete )
129+ close_walfile (char * basedir ,char * walname ,bool segment_complete )
125130{
126131off_t currpos = lseek (walfile ,0 ,SEEK_CUR );
127132
@@ -143,8 +148,10 @@ close_walfile(int walfile, char *basedir, char *walname, bool segment_complete)
143148{
144149fprintf (stderr ,_ ("%s: could not close file %s: %s\n" ),
145150progname ,walname ,strerror (errno ));
151+ walfile = -1 ;
146152return false;
147153}
154+ walfile = -1 ;
148155
149156/*
150157 * Rename the .partial file only if we've completed writing the whole
@@ -271,7 +278,6 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
271278char current_walfile_name [MAXPGPATH ];
272279PGresult * res ;
273280char * copybuf = NULL ;
274- int walfile = -1 ;
275281int64 last_status = -1 ;
276282XLogRecPtr blockpos = InvalidXLogRecPtr ;
277283
@@ -315,6 +321,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
315321{
316322fprintf (stderr ,_ ("%s: could not start replication: %s\n" ),
317323progname ,PQresultErrorMessage (res ));
324+ PQclear (res );
318325return false;
319326}
320327PQclear (res );
@@ -341,9 +348,9 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
341348 */
342349if (stream_stop && stream_stop (blockpos ,timeline , false))
343350{
344- if (walfile != -1 )
351+ if (walfile != -1 && ! close_walfile ( basedir , current_walfile_name , rename_partial ) )
345352/* Potential error message is written by close_walfile */
346- return close_walfile ( walfile , basedir , current_walfile_name , rename_partial ) ;
353+ goto error ;
347354return true;
348355}
349356
@@ -370,7 +377,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
370377{
371378fprintf (stderr ,_ ("%s: could not send feedback packet: %s" ),
372379progname ,PQerrorMessage (conn ));
373- return false ;
380+ goto error ;
374381}
375382
376383last_status = now ;
@@ -421,14 +428,14 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
421428{
422429fprintf (stderr ,_ ("%s: select() failed: %s\n" ),
423430progname ,strerror (errno ));
424- return false ;
431+ goto error ;
425432}
426433/* Else there is actually data on the socket */
427434if (PQconsumeInput (conn )== 0 )
428435{
429436fprintf (stderr ,_ ("%s: could not receive data from WAL stream: %s\n" ),
430437progname ,PQerrorMessage (conn ));
431- return false ;
438+ goto error ;
432439}
433440continue ;
434441}
@@ -439,7 +446,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
439446{
440447fprintf (stderr ,_ ("%s: could not read copy data: %s\n" ),
441448progname ,PQerrorMessage (conn ));
442- return false ;
449+ goto error ;
443450}
444451if (copybuf [0 ]== 'k' )
445452{
@@ -451,21 +458,21 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
451458{
452459fprintf (stderr ,_ ("%s: keepalive message is incorrect size: %d\n" ),
453460progname ,r );
454- return false ;
461+ goto error ;
455462}
456463continue ;
457464}
458465else if (copybuf [0 ]!= 'w' )
459466{
460467fprintf (stderr ,_ ("%s: unrecognized streaming header: \"%c\"\n" ),
461468progname ,copybuf [0 ]);
462- return false ;
469+ goto error ;
463470}
464471if (r < STREAMING_HEADER_SIZE + 1 )
465472{
466473fprintf (stderr ,_ ("%s: streaming header too small: %d\n" ),
467474progname ,r );
468- return false ;
475+ goto error ;
469476}
470477
471478/* Extract WAL location for this block */
@@ -483,7 +490,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
483490{
484491fprintf (stderr ,_ ("%s: received xlog record for offset %u with no file open\n" ),
485492progname ,xlogoff );
486- return false ;
493+ goto error ;
487494}
488495}
489496else
@@ -494,7 +501,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
494501{
495502fprintf (stderr ,_ ("%s: got WAL data offset %08x, expected %08x\n" ),
496503progname ,xlogoff , (int )lseek (walfile ,0 ,SEEK_CUR ));
497- return false ;
504+ goto error ;
498505}
499506}
500507
@@ -520,7 +527,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
520527basedir ,current_walfile_name );
521528if (walfile == -1 )
522529/* Error logged by open_walfile */
523- return false ;
530+ goto error ;
524531}
525532
526533if (write (walfile ,
@@ -532,7 +539,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
532539bytes_to_write ,
533540current_walfile_name ,
534541strerror (errno ));
535- return false ;
542+ goto error ;
536543}
537544
538545/* Write was successful, advance our position */
@@ -544,11 +551,10 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
544551/* Did we reach the end of a WAL segment? */
545552if (blockpos .xrecoff %XLOG_SEG_SIZE == 0 )
546553{
547- if (!close_walfile (walfile , basedir ,current_walfile_name , false))
554+ if (!close_walfile (basedir ,current_walfile_name , false))
548555/* Error message written in close_walfile() */
549- return false ;
556+ goto error ;
550557
551- walfile = -1 ;
552558xlogoff = 0 ;
553559
554560if (stream_stop != NULL )
@@ -577,8 +583,22 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
577583{
578584fprintf (stderr ,_ ("%s: unexpected termination of replication stream: %s\n" ),
579585progname ,PQresultErrorMessage (res ));
580- return false ;
586+ goto error ;
581587}
582588PQclear (res );
589+
590+ if (copybuf != NULL )
591+ PQfreemem (copybuf );
592+ if (walfile != -1 && close (walfile )!= 0 )
593+ fprintf (stderr ,_ ("%s: could not close file %s: %s\n" ),
594+ progname ,current_walfile_name ,strerror (errno ));
583595return true;
596+
597+ error :
598+ if (copybuf != NULL )
599+ PQfreemem (copybuf );
600+ if (walfile != -1 && close (walfile )!= 0 )
601+ fprintf (stderr ,_ ("%s: could not close file %s: %s\n" ),
602+ progname ,current_walfile_name ,strerror (errno ));
603+ return false;
584604}