From dfc8e7f6b8de021628046c004995843eaa78e0b7 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sun, 9 Apr 2006 22:29:42 +0000 Subject: [PATCH] better fix for ITS#4483 --- doc/man/man3/lber-encode.3 | 24 ++++++++++++++++++++---- include/lber.h | 12 +++++++++++- libraries/liblber/etest.c | 4 ++-- libraries/liblber/io.c | 19 +++++++++++++------ libraries/libldap/abandon.c | 2 +- libraries/libldap/request.c | 2 +- libraries/libldap/unbind.c | 2 +- servers/slapd/result.c | 4 ++-- 8 files changed, 51 insertions(+), 18 deletions(-) diff --git a/doc/man/man3/lber-encode.3 b/doc/man/man3/lber-encode.3 index 4c917b0a98..ad43d0d0d4 100644 --- a/doc/man/man3/lber-encode.3 +++ b/doc/man/man3/lber-encode.3 @@ -3,7 +3,7 @@ .\" Copyright 1998-2006 The OpenLDAP Foundation All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. .SH NAME -ber_alloc_t, ber_flush, ber_printf, ber_put_int, ber_put_enum, ber_put_ostring, ber_put_string, ber_put_null, ber_put_boolean, ber_put_bitstring, ber_start_seq, ber_start_set, ber_put_seq, ber_put_set \- LBER simplified Basic Encoding Rules library routines for encoding +ber_alloc_t, ber_flush, ber_flush2, ber_printf, ber_put_int, ber_put_enum, ber_put_ostring, ber_put_string, ber_put_null, ber_put_boolean, ber_put_bitstring, ber_start_seq, ber_start_set, ber_put_seq, ber_put_set \- LBER simplified Basic Encoding Rules library routines for encoding .SH LIBRARY OpenLDAP LBER (liblber, -llber) .SH SYNOPSIS @@ -13,6 +13,8 @@ OpenLDAP LBER (liblber, -llber) .LP .BI "int ber_flush(Sockbuf *" sb ", BerElement *" ber ", int " freeit ");" .LP +.BI "int ber_flush2(Sockbuf *" sb ", BerElement *" ber ", int " freeit ");" +.LP .BI "int ber_printf(BerElement *" ber ", const char *" fmt ", ...);" .LP .BI "int ber_put_int(BerElement *" ber ", ber_int_t " num ", ber_tag_t " tag ");" @@ -56,7 +58,7 @@ are to allocate a BER element for encoding, .BR ber_printf () to do the actual encoding, and -.BR ber_flush () +.BR ber_flush2 () to actually write the element. The other routines are provided for those applications that need more control than .BR ber_printf () @@ -70,7 +72,7 @@ routine is used to allocate a new BER element. It should be called with an argument of LBER_USE_DER. .LP The -.BR ber_flush () +.BR ber_flush2 () routine is used to actually write the element to a socket (or file) descriptor, once it has been fully encoded (using .BR ber_printf () @@ -78,7 +80,21 @@ and friends). See .BR lber-sockbuf (3) for more details on the Sockbuf implementation of the \fIsb\fP parameter. If the \fIfreeit\fP parameter is non-zero, the supplied \fIber\fP will -be freed after its contents have been flushed. +be freed. +If \fILBER_FLUSH_FREE_ON_SUCCESS\fP is used, the \fIber\fP is only freed +when successfully flushed, otherwise it is left intact; +if \fILBER_FLUSH_FREE_ON_ERROR\fP is used, the \fIber\fP is only freed +when an error occurs, otherwise it is left intact; +if \fILBER_FLUSH_FREE_ALWAYS\fP is used, the \fIber\fP is freed anyway. +This function differs from the original +.BR ber_flush (3) +function, whose behavior corresponds to that indicated +for \fILBER_FLUSH_FREE_ON_SUCCESS\fP. +Note that in the future, the behavior of +.BR ber_flush (3) +with \fIfreeit\fP non-zero might change into that of +.BR ber_flush2 (3) +with \fIfreeit\fP set to \fILBER_FLUSH_FREE_ALWAYS\fP. .LP The .BR ber_printf () diff --git a/include/lber.h b/include/lber.h index 3017d56181..522ff4c887 100644 --- a/include/lber.h +++ b/include/lber.h @@ -423,10 +423,20 @@ LBER_F( void ) ber_free_buf LDAP_P(( BerElement *ber )); LBER_F( int ) -ber_flush LDAP_P(( +ber_flush2 LDAP_P(( Sockbuf *sb, BerElement *ber, int freeit )); +#define LBER_FLUSH_FREE_NEVER (0x0) /* traditional behavior */ +#define LBER_FLUSH_FREE_ON_SUCCESS (0x1) /* traditional behavior */ +#define LBER_FLUSH_FREE_ON_ERROR (0x2) +#define LBER_FLUSH_FREE_ALWAYS (LBER_FLUSH_FREE_ON_SUCCESS|LBER_FLUSH_FREE_ON_ERROR) + +LBER_F( int ) +ber_flush LDAP_P(( + Sockbuf *sb, + BerElement *ber, + int freeit )); /* DEPRECATED */ LBER_F( BerElement * ) ber_alloc LDAP_P(( void )); /* DEPRECATED */ diff --git a/libraries/liblber/etest.c b/libraries/liblber/etest.c index 6573557552..c6befe12d2 100644 --- a/libraries/liblber/etest.c +++ b/libraries/liblber/etest.c @@ -171,8 +171,8 @@ main( int argc, char **argv ) return( EXIT_FAILURE ); } - if ( ber_flush( sb, ber, 1 ) == -1 ) { - perror( "ber_flush" ); + if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) == -1 ) { + perror( "ber_flush2" ); return( EXIT_FAILURE ); } diff --git a/libraries/liblber/io.c b/libraries/liblber/io.c index 1c162ecebc..befc02d9bc 100644 --- a/libraries/liblber/io.c +++ b/libraries/liblber/io.c @@ -200,10 +200,17 @@ ber_free( BerElement *ber, int freebuf ) int ber_flush( Sockbuf *sb, BerElement *ber, int freeit ) +{ + return ber_flush2( sb, ber, + freeit ? LBER_FLUSH_FREE_ON_SUCCESS + : LBER_FLUSH_FREE_NEVER ); +} + +int +ber_flush2( Sockbuf *sb, BerElement *ber, int freeit ) { ber_len_t towrite; ber_slen_t rc; - int retcode = 0; assert( sb != NULL ); assert( ber != NULL ); @@ -218,7 +225,7 @@ ber_flush( Sockbuf *sb, BerElement *ber, int freeit ) if ( sb->sb_debug ) { ber_log_printf( LDAP_DEBUG_TRACE, sb->sb_debug, - "ber_flush: %ld bytes to sd %ld%s\n", + "ber_flush2: %ld bytes to sd %ld%s\n", towrite, (long) sb->sb_fd, ber->ber_rwptr != ber->ber_buf ? " (re-flush)" : "" ); ber_log_bprint( LDAP_DEBUG_PACKETS, sb->sb_debug, @@ -233,17 +240,17 @@ ber_flush( Sockbuf *sb, BerElement *ber, int freeit ) rc = ber_int_sb_write( sb, ber->ber_rwptr, towrite ); #endif if ( rc <= 0 ) { - retcode = -1; - goto done; + if ( freeit & LBER_FLUSH_FREE_ON_ERROR ) ber_free( ber, 1 ); + return -1; } towrite -= rc; ber->ber_rwptr += rc; } done:; - if ( freeit ) ber_free( ber, 1 ); + if ( freeit & LBER_FLUSH_FREE_ON_SUCCESS ) ber_free( ber, 1 ); - return retcode; + return 0; } BerElement * diff --git a/libraries/libldap/abandon.c b/libraries/libldap/abandon.c index a69aa4dc20..bc9aae03e0 100644 --- a/libraries/libldap/abandon.c +++ b/libraries/libldap/abandon.c @@ -244,7 +244,7 @@ do_abandon( sb = ld->ld_sb; } - if ( ber_flush( sb, ber, 1 ) != 0 ) { + if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) != 0 ) { ld->ld_errno = LDAP_SERVER_DOWN; err = -1; } else { diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index 921d8aa760..c4a5514a1b 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -142,7 +142,7 @@ ldap_int_flush_request( { LDAPConn *lc = lr->lr_conn; - if ( ber_flush( lc->lconn_sb, lr->lr_ber, 0 ) != 0 ) { + if ( ber_flush2( lc->lconn_sb, lr->lr_ber, LBER_FLUSH_FREE_NEVER ) != 0 ) { if ( errno == EAGAIN ) { /* need to continue write later */ lr->lr_status = LDAP_REQST_WRITING; diff --git a/libraries/libldap/unbind.c b/libraries/libldap/unbind.c index 38a8e67a8a..da41633545 100644 --- a/libraries/libldap/unbind.c +++ b/libraries/libldap/unbind.c @@ -261,7 +261,7 @@ ldap_send_unbind( ld->ld_errno = LDAP_SUCCESS; /* send the message */ - if ( ber_flush( sb, ber, 1 ) == -1 ) { + if ( ber_flush2( sb, ber, LBER_FLUSH_FREE_ALWAYS ) == -1 ) { ld->ld_errno = LDAP_SERVER_DOWN; } diff --git a/servers/slapd/result.c b/servers/slapd/result.c index aefe3fac53..e412c6169e 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -167,7 +167,7 @@ static long send_ldap_ber( return 0; } - if ( ber_flush( conn->c_sb, ber, 0 ) == 0 ) { + if ( ber_flush2( conn->c_sb, ber, LBER_FLUSH_FREE_NEVER ) == 0 ) { break; } @@ -179,7 +179,7 @@ static long send_ldap_ber( * it's a hard error and return. */ - Debug( LDAP_DEBUG_CONNS, "ber_flush failed errno=%d reason=\"%s\"\n", + Debug( LDAP_DEBUG_CONNS, "ber_flush2 failed errno=%d reason=\"%s\"\n", err, sock_errstr(err), 0 ); if ( err != EWOULDBLOCK && err != EAGAIN ) { -- 2.39.5