/*
* Copyright (c) 2000-2002, 2004, 2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
#include "sm/generic.h"
SM_RCSID("@(#)$Id: fflush.c,v 1.19 2006/07/14 14:42:25 ca Exp $")
#include "sm/error.h"
#include "sm/time.h"
#include "sm/fcntl.h"
#include "sm/string.h"
#include "sm/io.h"
#include "sm/assert.h"
#include "io-int.h"
/*
** SM_IO_FLUSH -- flush the buffer for a 'fp' to the "file"
**
** Flush a single file. We don't allow this function to flush
** all open files when fp==NULL any longer.
**
** Parameters:
** fp -- the file pointer buffer to flush
**
** Results:
** usual sm_error code
*/
sm_ret_T
sm_io_flush(sm_file_T *fp)
{
SM_IS_FP(fp);
if ((f_flags(*fp) & (SMWR | SMRW)) == 0)
{
/*
** The file is not opened for writing, so it cannot be flushed
** (writable means SMWR [write] or SMRW [read/write].
*/
return sm_error_perm(SM_EM_IO, EBADF);
}
/* Now do the flush */
return sm_flush(fp);
}
/*
** SM_FLUSH -- perform the actual flush
**
** Assumes that 'fp' has been validated before this function called.
**
** Parameters:
** fp -- file pointer to be flushed
**
** Results:
** usual sm_error code
*/
sm_ret_T
sm_flush(sm_file_T *fp)
{
uchar *p;
ssize_t t;
int n;
sm_f_flags_T fl;
sm_ret_T res;
SM_IS_FP(fp);
fl = f_flags(*fp);
if ((fl & SMWR) == 0)
return SM_SUCCESS;
if (fl & (SMSTR|SMSTRSTR))
{
*f_p(*fp) = '\0';
return SM_SUCCESS;
}
p = f_bfbase(*fp);
if (p == NULL)
return SM_SUCCESS;
n = f_p(*fp) - p; /* write this much */
/*
** Set these immediately to avoid problems with longjmp and to allow
** exchange buffering (via setvbuf) in user write function.
*/
f_p(*fp) = p;
f_w(*fp) = fl & SMNBF ? 0 : f_bfsize(*fp);
for (; n > 0; n -= t, p += t)
{
res = (*f_write(*fp))(fp, p, n, &t);
if (sm_is_err(res))
{
/*
** Notice: f_p/f_w are not correct now!
** Hence this I/O error is not correctible.
** Should we try to fix f_p/f_w? That would require
** shifting the buffer content since we may have
** written a part.
*/
f_flags(*fp) |= SMERR;
#if SM_IO_ERR_VAL
f_error(*fp) = res;
#endif
return res;
}
}
return SM_SUCCESS;
}
syntax highlighted by Code2HTML, v. 0.9.1