libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] Can I get the entire MHD log without depends on C fu


From: silvioprog
Subject: Re: [libmicrohttpd] Can I get the entire MHD log without depends on C function like sprintf()?
Date: Wed, 2 Mar 2016 23:11:05 -0300

Hello Martin,

I meant "when you pass a va_list to a function, it is assumed that it will be 'consumed' by the called function". So, as I use two functions, the params is freed by the first one.

Consider the following MHD log error:

'Failed to bind to port 8080: Address already in use'#10 // #10 is similar to \n

If you try:

function _vscprintf(format: pcchar; ap: va_list): cint; cdecl;
begin
  Result := vsnprintf(nil, 0, format, ap);
end;

...

var
  VLength: Integer;
  VBuffer: AnsiString;
begin
  VLength := _vscprintf(AFmt, AArgs); // AArgs is my "va_list", and the _vscprintf() frees it here
  SetLength(VBuffer, VLength);
  VLength := vsnprintf(@VBuffer[1], VLength, AFmt, AArgs); // AArgs was freed by _vscprintf
  SetLength(VBuffer, VLength);
  WriteLn(VBuffer); 
end;

It prints:

'Failed to bind to port 4278124287: (null)'#10

Because the params was freed. Pascal doesn't have the C++ va_copy function, so I can't use a tip like this:

http://stackoverflow.com/questions/4785381/replacement-for-ms-vscprintf-on-macos-linux

But I'm also not sure about passing the NULL to the vsnprintf, so I choose a known approach, that's fill a dynamic array:

var
  VLength: Integer;
  VResult: RawByteString;
  VBuffer: array[0..1024] of AnsiChar; // as Christian said, 1024 sounds a good size
begin
  VLength := vsnprintf(VBuffer, Length(VBuffer), AFmt, AArgs); // Pascal already declare the "vsnprintf(VBuffer" as "vsnprintf(@VBuffer[1]"
  SetString(VResult, PAnsiChar(VBuffer), VLength);
  SetCodePage(VResult, CP_UTF8, False);
  WriteLn(VResult); // I need the end string as UTF-8 string
end;

And finally I got the correct buffer.

But it was just for fix my code on Linux, on Windows I use the _vscprintf() function, but if in the future I could find some function like va_copy() for Pascal, I can easily update my code to use that. :-)

On Tue, Mar 1, 2016 at 4:57 AM, Martin Bonner <address@hidden> wrote:

Silvio:  What do you mean by „I can’t use vsnprintf(NULL, 0, fmt, args) on Pascal because it frees the arguments”?  What frees what arguments? 

Would it help to use “char buffer[1]; vsnprintf(buffer, sizeof(buffer), fmt, args)”?  (It still ought to return the total size you need).  I’m not sure that passing NULL as the buffer is legal (even when the count is zero).

 

Also beware: I have a feeling that Visual Studio 2015 handles vsnprintf correctly for

overflow (in that it always nul-terminates), but earlier versions do not.  Of course, if you are going to go round again and just allocate a large enough buffer, that doesn’t matter.


--
Silvio Clécio

reply via email to

[Prev in Thread] Current Thread [Next in Thread]