]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Provide more opportunity for the remote side in sqlite3-rsync to send error
authordrh <>
Sun, 15 Sep 2024 18:37:34 +0000 (18:37 +0000)
committerdrh <>
Sun, 15 Sep 2024 18:37:34 +0000 (18:37 +0000)
messages back to the local side.  Be sure to invoke pclose2() when done.

FossilOrigin-Name: 23a63505152ff995e4ce0963dc4ab9f76ed55da7e7f5e1b85a2577473642e3ad

manifest
manifest.uuid
tool/sqlite3-rsync.c

index 3a6304a5394d24d07119ca7e4846bc4ebd73f59b..fcc4a19edea6e8ada72845ca0723828e64cbf0a5 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\ssubsequent\schanges\sto\ssqlite-rsync\sthat\swere\saccidentally\smissed\sby\nthe\sprior\scheck-in.
-D 2024-09-14T16:52:45.740
+C Provide\smore\sopportunity\sfor\sthe\sremote\sside\sin\ssqlite3-rsync\sto\ssend\serror\nmessages\sback\sto\sthe\slocal\sside.\s\sBe\ssure\sto\sinvoke\spclose2()\swhen\sdone.
+D 2024-09-15T18:37:34.119
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -2174,7 +2174,7 @@ F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd
 F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x
 F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60
 F tool/sqldiff.c 847fc8fcfddf5ce4797b7394cad6372f2f5dc17d8186e2ef8fb44d50fae4f44a
-F tool/sqlite3-rsync.c 00c9b4483851ca0337dff4b544ee39dffa8cdbe9dc55cd51d391590fd1f03763
+F tool/sqlite3-rsync.c dfcfd6b9994b7fc63b0aaba86caf8451ccab4ea7948c3a5137bc8582fd305505
 F tool/sqlite3_analyzer.c.in 8da2b08f56eeac331a715036cf707cc20f879f231362be0c22efd682e2b89b4f
 F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
@@ -2213,8 +2213,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P b7a8ce4c8c5fc6a3b4744d412d96f99d2452eb4086ad84472511da3b4d6afec6 129aca54f6b791c222b51f3eb01569e1e569269860e153b005140eb65af378b9
-R 3fe2d7eb1050bd322cb4e381c1c28c99
+P 50762ba0783a04e0dcd9456a1ae17d875b0a9272f2f09854a23d9d5253761e9f
+R 2c49475f6717a04e54580dcd0fa36eb0
 U drh
-Z 5104838c8e0c55c4caf222e0f2dc7147
+Z 06be86caecfa360efd4dbe55e1ffa14d
 # Remove this line to create a well-formed Fossil manifest.
index e011175dd428ebb7fb090a5a4e71cac124d36455..f41bb339ce32a93bdd25981f37698b0f309f4a5a 100644 (file)
@@ -1 +1 @@
-50762ba0783a04e0dcd9456a1ae17d875b0a9272f2f09854a23d9d5253761e9f
+23a63505152ff995e4ce0963dc4ab9f76ed55da7e7f5e1b85a2577473642e3ad
index 237ff8df5aa3236af5493b39a26474db6a63d020..4def6b982cd6b5325d52a2828ac1b34c36dc27f5 100644 (file)
@@ -50,6 +50,7 @@ struct SQLiteRsync {
   FILE *pLog;              /* Duplicate output here if not NULL */
   sqlite3 *db;             /* Database connection */
   int nErr;                /* Number of errors encountered */
+  int nWrErr;              /* Number of failed attempts to write on the pipe */
   u8 eVerbose;             /* Bigger for more output.  0 means none. */
   u8 bCommCheck;           /* True to debug the communication protocol */
   u8 isRemote;             /* On the remote side of a connection */
@@ -844,7 +845,7 @@ static int readUint32(SQLiteRsync *p, unsigned int *pU){
     p->nIn += 4;
     return 0;
   }else{
-    p->nErr++;
+    logError(p, "failed to read a 32-bit integer\n");
     return 1;
   }
 }
@@ -863,7 +864,8 @@ static int writeUint32(SQLiteRsync *p, unsigned int x){
   buf[0] = x;
   if( p->pLog ) fwrite(buf, sizeof(buf), 1, p->pLog);
   if( fwrite(buf, sizeof(buf), 1, p->pOut)!=1 ){
-    logError(p, "failed to write 32-bit integer 0x%x", x);
+    logError(p, "failed to write 32-bit integer 0x%x\n", x);
+    p->nWrErr++;
     return 1;
   }
   p->nOut += 4;
@@ -914,7 +916,7 @@ void readBytes(SQLiteRsync *p, int nByte, void *pData){
   if( fread(pData, 1, nByte, p->pIn)==nByte ){
     p->nIn += nByte;
   }else{
-    logError(p, "failed to read %d bytes", nByte);
+    logError(p, "failed to read %d bytes\n", nByte);
   }
 }
 
@@ -925,7 +927,8 @@ void writeBytes(SQLiteRsync *p, int nByte, const void *pData){
   if( fwrite(pData, 1, nByte, p->pOut)==nByte ){
     p->nOut += nByte;
   }else{
-    logError(p, "failed to write %d bytes", nByte);
+    logError(p, "failed to write %d bytes\n", nByte);
+    p->nWrErr++;
   }
 }
 
@@ -1236,7 +1239,7 @@ static void originSide(SQLiteRsync *p){
   }
   
   /* Respond to message from the replica */
-  while( p->nErr==0 && (c = readByte(p))!=EOF && c!=REPLICA_END ){
+  while( p->nErr<=p->nWrErr && (c = readByte(p))!=EOF && c!=REPLICA_END ){
     switch( c ){
       case REPLICA_BEGIN: {
         /* This message is only sent if the replica received an origin-protocol
@@ -1292,7 +1295,7 @@ static void originSide(SQLiteRsync *p){
                "SELECT pgno, data"
                "  FROM badHash JOIN sqlite_dbpage('main') USING(pgno)");
         if( pStmt==0 ) break;
-        while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 ){
+        while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 && p->nWrErr==0 ){
           unsigned int pgno = (unsigned int)sqlite3_column_int64(pStmt,0);
           const void *pContent = sqlite3_column_blob(pStmt, 1);
           if( pgno==1 ){
@@ -1312,7 +1315,7 @@ static void originSide(SQLiteRsync *p){
                  " WHERE pgno=1"
           );
           if( pStmt==0 ) break;
-          while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 ){
+          while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 &&p->nWrErr==0 ){
             const void *pContent = sqlite3_column_blob(pStmt, 0);
             writeByte(p, ORIGIN_PAGE);
             writeUint32(p, 1);
@@ -1324,7 +1327,8 @@ static void originSide(SQLiteRsync *p){
         writeByte(p, ORIGIN_TXN);
         writeUint32(p, nPage);
         writeByte(p, ORIGIN_END);
-        goto origin_end;
+        fflush(p->pOut);
+        break;
       }
       default: {
         reportError(p, "Unknown message 0x%02x %lld bytes into conversation",
@@ -1334,7 +1338,6 @@ static void originSide(SQLiteRsync *p){
     }
   }
 
-origin_end:
   if( pCkHash ) sqlite3_finalize(pCkHash);
   closeDb(p);
 }
@@ -1385,7 +1388,7 @@ static void replicaSide(SQLiteRsync *p){
   /* Respond to message from the origin.  The origin will initiate the
   ** the conversation with an ORIGIN_BEGIN message.
   */
-  while( p->nErr==0 && (c = readByte(p))!=EOF && c!=ORIGIN_END ){
+  while( p->nErr<=p->nWrErr && (c = readByte(p))!=EOF && c!=ORIGIN_END ){
     switch( c ){
       case ORIGIN_MSG:
       case ORIGIN_ERROR: {
@@ -1448,7 +1451,7 @@ static void replicaSide(SQLiteRsync *p){
                    "SELECT hash(data) FROM sqlite_dbpage"
                    " WHERE pgno<=min(%d,%d)"
                    " ORDER BY pgno", nRPage, nOPage);
-        while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 ){
+        while( sqlite3_step(pStmt)==SQLITE_ROW && p->nErr==0 && p->nWrErr==0 ){
           const unsigned char *a = sqlite3_column_blob(pStmt, 0);
           writeByte(p, REPLICA_HASH);
           writeBytes(p, 20, a);
@@ -1805,6 +1808,7 @@ int main(int argc, char const * const *argv){
     }
     originSide(&ctx);
   }
+  pclose2(ctx.pIn, ctx.pOut, childPid);
   if( ctx.pLog ) fclose(ctx.pLog);
   tmEnd = currentTime();
   tmElapse = tmEnd - tmStart;  /* Elapse time in milliseconds */