-
February 2nd, 2010, 03:33 AM
#1
socket receive a chunk at a time
On linux the same call to fwrite works correctly (errno==0),
on windows i get ERRNO==22 if the "size" parameter is somewhat big (e.g. "103429"). :-/
see the code:
Code:
// first i open the file
FILE* request_file = fopen( pathname, "wb" );
if(request_file == NULL)
{
// error
return;
}
// second, try to write my buffer (already filled)
size_t written_bytes = 0;
if( parsed_request->body != NULL )
{
errno=0;
written_bytes = fwrite((parsed_request->body), 1, (size_t)(parsed_request->content_length), request_file);
perror("fwrite");
}
// third, check fwrite return value
if( written_bytes < 0 )
{
// write error
return;
}
else if( written_bytes != (parsed_request->content_length) )
{
// error - partial body received
return;
}
// else fwrite succeed
NOTE:
if i replace "(size_t)(parsed_request->content_length)" with a small constant (e.g. "50"), fwrite succeed!
NOTE2:
I get the same behavior with "_write"...
P.S.
To give you more context details, i'm using the Mingw compiler.
I've defined the macro "_MT" to enable multi-threaded stdlib.
Maybe this has some side-effect on fwrite?
Since the call is not atomic with a big buffer, maybe fwrite fails to preserve thread-safeness?
I've tried to remove "_MT" in the makefile but fwrite still fails. :-(
Last edited by hi1; February 6th, 2010 at 10:55 PM.
-
February 2nd, 2010, 04:51 AM
#2
Re: fwrite ERRNO 22 with big (?) size
The arguments 2 and 3 should be exchanged. This is a common mistake, and, usually, it does not matter, but maybe it matters here.
Instead of
Code:
written_bytes = fwrite((parsed_request->body), 1, (size_t)(parsed_request->content_length), request_file);
Write
Code:
written_bytes = fwrite((parsed_request->body), (size_t)(parsed_request->content_length), 1, request_file);
Check the value in parsed_request->content_length.
Is it the size of parsed_request->body?
N.B. Write your code between [code] and [/code]. It will be placed in a nice rectangle and spaces at the beginning of lines will be saved.
EDIT: Excuse-me, forget what I have said.
Last edited by olivthill2; February 2nd, 2010 at 10:00 AM.
-
February 2nd, 2010, 05:09 AM
#3
Re: fwrite ERRNO 22 with big (?) size
Originally Posted by olivthill2
The arguments 2 and 3 should be exchanged. This is a common mistake, and, usually, it does not matter, but maybe it matters here.
Instead of
Code:
written_bytes = fwrite((parsed_request->body), 1, (size_t)(parsed_request->content_length), request_file);
Write
Code:
written_bytes = fwrite((parsed_request->body), (size_t)(parsed_request->content_length), 1, request_file);
I already tried that. Still get ERRNO==22. :-(
BTW, the correct way should be the first one. See http://www.opengroup.org/onlinepubs/...ns/fwrite.html):
I mean to write nitems=(parsed_request->content_length) bytes (size=1) from ptr=(parsed_request->body) to stream=request_file.
Originally Posted by olivthill2
Check the value in parsed_request->content_length.
Is it the size of parsed_request->body?
Yes it is.
Last edited by hi1; February 2nd, 2010 at 05:18 AM.
-
February 2nd, 2010, 10:31 AM
#4
Re: fwrite ERRNO 22 with big (?) size
Don't call perror unless you detect an error.
gg
-
February 2nd, 2010, 01:13 PM
#5
Re: fwrite ERRNO 22 with big (?) size
Originally Posted by Codeplug
Don't call perror unless you detect an error.
gg
That call is for debug purpose only.
I'll remove that once i've fixed the issue.
-
February 2nd, 2010, 01:27 PM
#6
Re: fwrite ERRNO 22 with big (?) size
What issue? You haven't shown any code that actually performs error checking.
http://www.opengroup.org/onlinepubs/...ons/errno.html
gg
Last edited by Codeplug; February 2nd, 2010 at 01:31 PM.
-
February 2nd, 2010, 01:31 PM
#7
Re: fwrite ERRNO 22 with big (?) size
Originally Posted by Codeplug
What issue? You haven't shown any code that actually performs error checking.
gg
Ok, now i've added the checks.
I've omitted them since they did not seem relevant to me.
Last edited by hi1; February 2nd, 2010 at 01:34 PM.
-
February 2nd, 2010, 02:34 PM
#8
Re: fwrite ERRNO 22 with big (?) size
Originally Posted by hi1
Ok, now i've added the checks.
I've omitted them since they did not seem relevant to me.
So where exactly in your code do you see that errno is 22?
Did you step through your code under debugger?
What is the value of written_bytes? content_length? And what is its type?
Please note that errno is a global variable, it could be set in some other place in your code.
For example, if your parsed_request->body is 0, you bypass the line
Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
Convenience and productivity tools for Microsoft Visual Studio:
FeinWindows - replacement windows manager for Visual Studio, and more...
-
February 2nd, 2010, 03:00 PM
#9
Re: fwrite ERRNO 22 with big (?) size
Originally Posted by VladimirF
So where exactly in your code do you see that errno is 22?
Did you step through your code under debugger?
No, perror always output "Invalid Argument" (that is, errno 22).
I've also disabled multi-threading so there can't be any interference with other threads...
"content_length" is of "unsigned int" type. It was "103429" when fwrite failed.
BTW, with smaller values of "content_length" fwrite succeed.
I'm quite sure fwrite fails because of the "nitems" param, but i can't understand why.
Last edited by hi1; February 2nd, 2010 at 03:10 PM.
-
February 2nd, 2010, 03:32 PM
#10
Re: fwrite ERRNO 22 with big (?) size
How do you know that fwrite fails? Can we see the code?
gg
-
February 2nd, 2010, 04:05 PM
#11
Re: fwrite ERRNO 22 with big (?) size
Originally Posted by Codeplug
How do you know that fwrite fails? Can we see the code?
gg
Boy, it's just what i've posted:
If fwrite succeed errno remains 0 and perror outputs "No error",
otherwise errno!=0 and perror output something meaningful.
-
February 2nd, 2010, 04:19 PM
#12
Re: fwrite ERRNO 22 with big (?) size
OK, last question: how sure are you that content_length matches the length of body?
If body is shorter, it will cause access violation during write() that will be caught inside that function and translated into EINVAL.
Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
Convenience and productivity tools for Microsoft Visual Studio:
FeinWindows - replacement windows manager for Visual Studio, and more...
-
February 2nd, 2010, 04:50 PM
#13
Re: fwrite ERRNO 22 with big (?) size
>> http://www.opengroup.org/onlinepubs/...ons/errno.html
... The value of errno shall be defined only after a call to a function for which it is explicitly stated to be set and until it is changed by the next function call or if the application assigns it a value. The value of errno should only be examined when it is indicated to be valid by a function's return value. ...
>> http://www.opengroup.org/onlinepubs/...ns/fwrite.html
RETURN VALUE
The fwrite() function shall return the number of elements successfully written, which may be less than nitems if a write error is encountered. If size or nitems is 0, fwrite() shall return 0 and the state of the stream remains unchanged. Otherwise, if a write error occurs, the error indicator for the stream shall be set, [CX] and errno shall be set to indicate the error.
So you can only check errno if frwite() returns a value less than the number of elements requested, or if ferror() returns non-zero.
gg
-
February 2nd, 2010, 06:59 PM
#14
Re: fwrite ERRNO 22 with big (?) size
Originally Posted by VladimirF
OK, last question: how sure are you that content_length matches the length of body?
If body is shorter, it will cause access violation during write() that will be caught inside that function and translated into EINVAL.
Yes i've thinked of it too, but the test case i've used for testing is build so that the content_length matches exactly the length of the body buffer.
So you can assume that this condition is always true.
Originally Posted by Codeplug
So you can only check errno if frwite() returns a value less than the number of elements requested, or if ferror() returns non-zero.
gg
Ok, but the problem here is not if the errno value is valid or not.
The problem is that fwrite does not write anything (written_bytes==0) even if the arguments are correct.
Also note that (as i've already stated) that the very same code works correctly on Linux (written_bytes==103429),
so i'm quite sure that the program logic is correct.
I guess there must be "something" in the Windows context that makes fwrite behave differently.
I hope i've made myself clear. :-)
Last edited by hi1; February 2nd, 2010 at 07:04 PM.
-
February 2nd, 2010, 07:07 PM
#15
Re: fwrite ERRNO 22 with big (?) size
Originally Posted by hi1
...the test case i've used for testing is build so that the content_length matches exactly the length of the body buffer.
So you can assume that this condition is always true.
I prefer to assume that it isn't.
Could you look at your "body" in the debugger? Can you scroll the Memory window all the way to body+103429? Does it look OK?
Bottom line is - I can assure you that fwrite() can handle 100K on Windows.
Could you package your test case and post it here?
Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
Convenience and productivity tools for Microsoft Visual Studio:
FeinWindows - replacement windows manager for Visual Studio, and more...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|