better fix for ITS#4483

This commit is contained in:
Pierangelo Masarati 2006-04-09 22:29:42 +00:00
parent ca7e49fa74
commit dfc8e7f6b8
8 changed files with 51 additions and 18 deletions

View File

@ -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 ()

View File

@ -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 */

View File

@ -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 );
}

View File

@ -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 *

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}

View File

@ -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 ) {