3838#define STREAMING_HEADER_SIZE (1+sizeof(WalDataMessageHeader))
3939#define STREAMING_KEEPALIVE_SIZE (1+sizeof(PrimaryKeepaliveMessage))
4040
41+ /* fd for currently open WAL file */
42+ static int walfile = -1 ;
43+
44+
4145/*
4246 * Open a new WAL file in the specified directory. Store the name
4347 * (not including the full directory) in namebuf. Assumes there is
@@ -96,6 +100,7 @@ open_walfile(XLogRecPtr startpoint, uint32 timeline, char *basedir, char *namebu
96100{
97101fprintf (stderr ,_ ("%s: could not pad WAL segment %s: %s\n" ),
98102progname ,fn ,strerror (errno ));
103+ free (zerobuf );
99104close (f );
100105unlink (fn );
101106return -1 ;
@@ -120,7 +125,7 @@ open_walfile(XLogRecPtr startpoint, uint32 timeline, char *basedir, char *namebu
120125 * completed writing the whole segment.
121126 */
122127static bool
123- close_walfile (int walfile , char * basedir ,char * walname ,bool segment_complete )
128+ close_walfile (char * basedir ,char * walname ,bool segment_complete )
124129{
125130off_t currpos = lseek (walfile ,0 ,SEEK_CUR );
126131
@@ -142,8 +147,10 @@ close_walfile(int walfile, char *basedir, char *walname, bool segment_complete)
142147{
143148fprintf (stderr ,_ ("%s: could not close file %s: %s\n" ),
144149progname ,walname ,strerror (errno ));
150+ walfile = -1 ;
145151return false;
146152}
153+ walfile = -1 ;
147154
148155/*
149156 * Rename the .partial file only if we've completed writing the whole
@@ -270,7 +277,6 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi
270277char current_walfile_name [MAXPGPATH ];
271278PGresult * res ;
272279char * copybuf = NULL ;
273- int walfile = -1 ;
274280int64 last_status = -1 ;
275281XLogRecPtr blockpos = InvalidXLogRecPtr ;
276282
@@ -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 %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}