.\" 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
.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 ");"
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 ()
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 ()
.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 ()
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 */
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 );
}
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 );
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,
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 *
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 {
{
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;
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;
}
return 0;
}
- if ( ber_flush( conn->c_sb, ber, 0 ) == 0 ) {
+ if ( ber_flush2( conn->c_sb, ber, LBER_FLUSH_FREE_NEVER ) == 0 ) {
break;
}
* 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 ) {