gnutls examples don't handle short writes correctly
I see the following pattern in examples (copy-pasted from doc/examples/ex-client-anon.c):
#define LOOP_CHECK(rval, cmd) \
do { \
rval = cmd; \
} while(rval == GNUTLS_E_AGAIN || rval == GNUTLS_E_INTERRUPTED); \
assert(rval >= 0)
#define MAX_BUF 1024
#define MSG "GET / HTTP/1.0\r\n\r\n"
...
LOOP_CHECK(ret, gnutls_record_send(session, MSG, strlen(MSG))); // no other loop, no nothing
If gnutls_record_send does a "short write", writing the buffer out only partially and returning less than strlen(MSG)
, the request won't be sent in a complete form and the example would hang.
The problematic short write handling holds true for other examples, say, echo server.
I believe we should fix the examples to handle short writes correctly, ideally in a coordinated, uniform manner.
Alternative options include:
- Modify
gnutls_record_send
to handle short writes correctly. This sounds like it even preserves the API guarantees, but I'm not sure it won't change behaviour non-trivially when non-blocking sockets are used, say, by introducing a performance regression. - Implement additional, simplified version of
gnutls_record_send
that'd handle short writes transparently, possibly alsoE_AGAIN
/E_INTERRUPTED
. Not sure how justified would that be.
Edited by Alexander Sosedkin