From 7f4be8c3f853010ed3f7ec636b3fb42033ce7b2f Mon Sep 17 00:00:00 2001 From: Don Hardman Date: Fri, 12 Jan 2024 15:28:32 +0700 Subject: [PATCH] Fix output from Buddy by chunkening it while using the same buffer decalred in the code --- src/searchd.cpp | 48 +++++++++++++++++++++--- src/searchdbuddy.cpp | 88 +++++++++++++++++++------------------------- src/sphinxutils.cpp | 2 - 3 files changed, 80 insertions(+), 58 deletions(-) diff --git a/src/searchd.cpp b/src/searchd.cpp index e3a34eadb3..725495c187 100644 --- a/src/searchd.cpp +++ b/src/searchd.cpp @@ -436,11 +436,47 @@ void sphLog ( ESphLogLevel eLevel, const char * sFmt, va_list ap ) // format the message if ( sFmt ) { - // need more space for tail zero and "\n" that added at sphLogEntry - int iSafeGap = 4; - int iBufSize = sizeof(sBuf)-iLen-iSafeGap; - vsnprintf ( sBuf+iLen, iBufSize, sFmt, ap ); - sBuf[ sizeof(sBuf)-iSafeGap ] = '\0'; + // Use vsnprintf to get the total length required for the formatted string + va_list ap_copy; + va_copy(ap_copy, ap); + int iRequiredLength = vsnprintf(NULL, 0, sFmt, ap_copy); + va_end(ap_copy); + + // Allocate a temporary buffer to hold the entire formatted message + char* sMessage = (char*)malloc(iRequiredLength + 1); // +1 for null terminator + if (!sMessage) + { + // Handle malloc failure if necessary + return; + } + + // Use vsnprintf again to write the formatted message into sMessage + va_copy(ap_copy, ap); + vsnprintf(sMessage, iRequiredLength + 1, sFmt, ap_copy); + va_end(ap_copy); + + // Now iterate over the message, writing it in chunks + for (int iOffset = 0; iOffset < iRequiredLength;) + { + // Calculate space left in sBuf after the banner and timestamp + int iSpaceLeft = sizeof(sBuf) - iLen - 1; // -1 for null terminator + + // Determine the chunk length (do not exceed the space left in sBuf) + int iChunkLength = (iRequiredLength - iOffset) < iSpaceLeft ? (iRequiredLength - iOffset) : iSpaceLeft; + + // Copy the next chunk of the message into the buffer + strncpy(sBuf + iLen, sMessage + iOffset, iChunkLength); + sBuf[iLen + iChunkLength] = '\0'; // Ensure null-termination + + // Log the current chunk + sphLogEntry(eLevel, sBuf, sTtyBuf); + + // Move the offset by the chunk length for the next iteration + iOffset += iChunkLength; + } + + // Free the allocated memory for the message + free(sMessage); } if ( sFmt && eLevel>SPH_LOG_INFO && g_iLogFilterLen ) @@ -490,7 +526,7 @@ void sphLog ( ESphLogLevel eLevel, const char * sFmt, va_list ap ) uLastEntry = uEntry; // do the logging - sphLogEntry ( eLevel, sBuf, sTtyBuf ); + // sphLogEntry ( eLevel, sBuf, sTtyBuf ); } void Shutdown (); // forward diff --git a/src/searchdbuddy.cpp b/src/searchdbuddy.cpp index 2bfb0746ee..fed434721a 100644 --- a/src/searchdbuddy.cpp +++ b/src/searchdbuddy.cpp @@ -133,56 +133,44 @@ static void AddTail ( Str_t tLine ) memcpy ( pDst, tLine.first, tLine.second ); } -static bool HasLineEnd ( Str_t tBuf, Str_t tLine ) -{ - const char * sEnd = tBuf.first + tBuf.second; - return ( ( tLine.first + tLine.second ) dLines; - sphSplitApply ( tSrc.first, tSrc.second, "\n\r", [&dLines] ( const char * pLine, int iLen ) { dLines.Add ( Str_t { pLine, iLen } ); } ); - - if ( !dLines.GetLength() ) - return; +static bool HasLineEnd(Str_t tBuf, Str_t tLine) { + if (tLine.second == 0) { + // Empty line, no content to check for line ending + return false; + } - // whole pipe buffer without line end - collect into line buffer - Str_t tLine0 = dLines[0]; - if ( !HasLineEnd ( tSrc, tLine0 ) ) - { - AddTail ( tLine0 ); - return; - } + // Get the last character of the line + const char lastChar = *(tLine.first + tLine.second - 1); + // Check if the last character is a line-ending character + return lastChar == '\n' || lastChar == '\r'; +} - // join pipe buffer with line buffer collected so far - if ( g_dLogBuf.GetLength() ) - { - sphInfo ( "[BUDDY] %.*s%.*s", g_dLogBuf.GetLength(), g_dLogBuf.Begin(), tLine0.second, tLine0.first ); - g_dLogBuf.Resize ( 0 ); - } else - { - sphInfo ( "[BUDDY] %.*s", tLine0.second, tLine0.first ); - } +static void LogPipe(Str_t tSrc) { + CSphVector dLines; + sphSplitApply(tSrc.first, tSrc.second, "\n\r", [&dLines](const char* pLine, int iLen) { + dLines.Add(Str_t{pLine, iLen}); + }); - if ( dLines.GetLength()==1 ) - return; + if (!dLines.GetLength()) { + return; + } - for ( int i=1; istop(); g_pPipe.reset(); - g_pIOS.reset(); + g_pIOS.reset(); g_pIOS.reset ( new boost::asio::io_service ); g_pPipe.reset ( new boost::process::async_pipe ( *g_pIOS ) ); @@ -361,7 +349,7 @@ CSphString GetUrl ( const ListenerDesc_t & tDesc ) { char sAddrBuf [ SPH_ADDRESS_SIZE ]; sphFormatIP ( sAddrBuf, sizeof(sAddrBuf), tDesc.m_uIP ); - + CSphString sURI; sURI.SetSprintf ( "http://%s:%d", sAddrBuf, tDesc.m_iPort ); @@ -414,7 +402,7 @@ void BuddyStart ( const CSphString & sConfigPath, bool bHasBuddyPath, const VecT g_sListener4Buddy.cstr(), ( bTelemetry ? "" : "--disable-telemetry" ), iThreads ); - + CSphString sErorr; BuddyState_e eBuddy = TryToStart ( g_sStartArgs.cstr(), sErorr ); @@ -559,7 +547,7 @@ bool ProcessHttpQueryBuddy ( HttpProcessResult_t & tRes, Str_t sSrcQuery, Option tRes.m_sError.SetSprintf ( "can not process /cli endpoint with User-Agent:Manticore Buddy" ); sphHttpErrorReply ( dResult, SPH_HTTP_STATUS_501, tRes.m_sError.cstr() ); } - + assert ( dResult.GetLength()>0 ); return tRes.m_bOk; } @@ -683,4 +671,4 @@ CSphString BuddyGetPath ( const CSphString & sConfigPath, bool bHasBuddyPath ) sphWarning ( "[BUDDY] no %s found at '%s', disabled", g_sDefaultBuddyName.cstr(), sPathBuddy2Module.cstr() ); return CSphString(); -} \ No newline at end of file +} diff --git a/src/sphinxutils.cpp b/src/sphinxutils.cpp index cc8e3d6474..f1139921cb 100644 --- a/src/sphinxutils.cpp +++ b/src/sphinxutils.cpp @@ -910,7 +910,6 @@ static KeyDesc_t g_dKeysIndex[] = { "access_blob_attrs", 0, nullptr }, { "access_doclists", 0, nullptr }, { "access_hitlists", 0, nullptr }, - { "access_dict", 0, nullptr }, { "stored_fields", 0, nullptr }, { "stored_only_fields", 0, nullptr }, { "docstore_block_size", 0, nullptr }, @@ -1035,7 +1034,6 @@ static KeyDesc_t g_dKeysSearchd[] = { "access_blob_attrs", 0, nullptr }, { "access_doclists", 0, nullptr }, { "access_hitlists", 0, nullptr }, - { "access_dict", 0, nullptr }, { "docstore_cache_size", 0, nullptr }, { "skiplist_cache_size", 0, nullptr }, { "ssl_cert", 0, nullptr },