diff options
author | 2006-10-07 04:45:39 +1000 | |
---|---|---|
committer | 2006-10-07 04:45:39 +1000 | |
commit | 184d58cd360569fa44aa088dab3421b832313424 (patch) | |
tree | 7c14112c444f009f138b33e77d5b8a354991e60a /env_universal_common.c | |
parent | bcf3024cf01f4b2d14b38de8fc24372d7b4e9127 (diff) |
Buffer calls to read() in the universal variable code
darcs-hash:20061006184539-ac50b-d8ecc4c45d0caae12cd60e32515a1218b37831d3.gz
Diffstat (limited to 'env_universal_common.c')
-rw-r--r-- | env_universal_common.c | 94 |
1 files changed, 77 insertions, 17 deletions
diff --git a/env_universal_common.c b/env_universal_common.c index ba798867..cf8dad1e 100644 --- a/env_universal_common.c +++ b/env_universal_common.c @@ -70,6 +70,21 @@ #define PARSE_ERR L"Unable to parse universal variable message: '%ls'" /** + ERROR string for internal buffered reader +*/ +#define ENV_UNIVERSAL_ERROR 0x100 + +/** + EAGAIN string for internal buffered reader +*/ +#define ENV_UNIVERSAL_AGAIN 0x101 + +/** + EOF string for internal buffered reader +*/ +#define ENV_UNIVERSAL_EOF 0x102 + +/** A variable entry. Stores the value of a variable and whether it should be exported. Obviously, it needs to be allocated large enough to fit the value string. @@ -134,39 +149,84 @@ void env_universal_common_destroy() hash_destroy( &env_universal_var ); } +static int read_byte( connection_t *src ) +{ + + if( src->buffer_consumed >= src->buffer_used ) + { + + int res; + + res = read( src->fd, src->buffer, ENV_UNIVERSAL_BUFFER_SIZE ); + + if( res < 0 ) + { + + if( errno == EAGAIN || + errno == EINTR ) + { + return ENV_UNIVERSAL_AGAIN; + } + + return ENV_UNIVERSAL_ERROR; + + } + + if( res == 0 ) + { + return ENV_UNIVERSAL_EOF; + } + + src->buffer_consumed = 0; + src->buffer_used = res; + } + + return src->buffer[src->buffer_consumed++]; + +} + void read_message( connection_t *src ) { while( 1 ) { - char b; - int read_res = read( src->fd, &b, 1 ); - wchar_t res=0; - if( read_res < 0 ) + int ib = read_byte( src ); + char b; + + wchar_t res=0; + + switch( ib ) { - if( errno != EAGAIN && - errno != EINTR ) + case ENV_UNIVERSAL_AGAIN: + { + return; + } + + case ENV_UNIVERSAL_ERROR: { debug( 2, L"Read error on fd %d, set killme flag", src->fd ); wperror( L"read" ); src->killme = 1; + return; } - return; - } - if( read_res == 0 ) - { - src->killme = 1; - debug( 3, L"Fd %d has reached eof, set killme flag", src->fd ); - if( src->input.used > 0 ) + + case ENV_UNIVERSAL_EOF: { - debug( 1, - L"Universal variable connection closed while reading command. Partial command recieved: '%ls'", - (wchar_t *)src->input.buff ); + src->killme = 1; + debug( 3, L"Fd %d has reached eof, set killme flag", src->fd ); + if( src->input.used > 0 ) + { + debug( 1, + L"Universal variable connection closed while reading command. Partial command recieved: '%ls'", + (wchar_t *)src->input.buff ); + } + return; } - return; } + b = (char)ib; + int sz = mbrtowc( &res, &b, 1, &src->wstate ); if( sz == -1 ) |