140266059SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro * Copyright (c) 2000-2001, 2005, 2006 Proofpoint, Inc. and its suppliers.
340266059SGregory Neil Shapiro * All rights reserved.
440266059SGregory Neil Shapiro * Copyright (c) 1990, 1993
540266059SGregory Neil Shapiro * The Regents of the University of California. All rights reserved.
640266059SGregory Neil Shapiro *
740266059SGregory Neil Shapiro * This code is derived from software contributed to Berkeley by
840266059SGregory Neil Shapiro * Chris Torek.
940266059SGregory Neil Shapiro *
1040266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set
1140266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of
1240266059SGregory Neil Shapiro * the sendmail distribution.
1340266059SGregory Neil Shapiro */
1440266059SGregory Neil Shapiro
1540266059SGregory Neil Shapiro #include <sm/gen.h>
16*4313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: fflush.c,v 1.46 2013-11-22 20:51:42 ca Exp $")
1740266059SGregory Neil Shapiro #include <unistd.h>
1840266059SGregory Neil Shapiro #include <errno.h>
194e4196cbSGregory Neil Shapiro #include <sm/time.h>
2040266059SGregory Neil Shapiro #include <signal.h>
2140266059SGregory Neil Shapiro #include <fcntl.h>
2240266059SGregory Neil Shapiro #include <string.h>
2340266059SGregory Neil Shapiro #include <sm/io.h>
2440266059SGregory Neil Shapiro #include <sm/assert.h>
2540266059SGregory Neil Shapiro #include <sm/setjmp.h>
2640266059SGregory Neil Shapiro #include "local.h"
2740266059SGregory Neil Shapiro #include <sm/conf.h>
2840266059SGregory Neil Shapiro
2940266059SGregory Neil Shapiro /*
3040266059SGregory Neil Shapiro ** SM_IO_FLUSH -- flush the buffer for a 'fp' to the "file"
3140266059SGregory Neil Shapiro **
3240266059SGregory Neil Shapiro ** Flush a single file. We don't allow this function to flush
3340266059SGregory Neil Shapiro ** all open files when fp==NULL any longer.
3440266059SGregory Neil Shapiro **
3540266059SGregory Neil Shapiro ** Parameters:
3640266059SGregory Neil Shapiro ** fp -- the file pointer buffer to flush
3740266059SGregory Neil Shapiro ** timeout -- time to complete the flush
3840266059SGregory Neil Shapiro **
3940266059SGregory Neil Shapiro ** Results:
4040266059SGregory Neil Shapiro ** Failure: SM_IO_EOF and sets errno
4140266059SGregory Neil Shapiro ** Success: 0 (zero)
4240266059SGregory Neil Shapiro */
4340266059SGregory Neil Shapiro
4440266059SGregory Neil Shapiro int
4540266059SGregory Neil Shapiro sm_io_flush(fp, timeout)
4640266059SGregory Neil Shapiro register SM_FILE_T *fp;
4740266059SGregory Neil Shapiro int SM_NONVOLATILE timeout;
4840266059SGregory Neil Shapiro {
4940266059SGregory Neil Shapiro int fd;
5040266059SGregory Neil Shapiro struct timeval to;
5140266059SGregory Neil Shapiro
5240266059SGregory Neil Shapiro SM_REQUIRE_ISA(fp, SmFileMagic);
5340266059SGregory Neil Shapiro
5440266059SGregory Neil Shapiro if ((fp->f_flags & (SMWR | SMRW)) == 0)
5540266059SGregory Neil Shapiro {
5640266059SGregory Neil Shapiro /*
5740266059SGregory Neil Shapiro ** The file is not opened for writing, so it cannot be flushed
5840266059SGregory Neil Shapiro ** (writable means SMWR [write] or SMRW [read/write].
5940266059SGregory Neil Shapiro */
6040266059SGregory Neil Shapiro
6140266059SGregory Neil Shapiro errno = EBADF;
6240266059SGregory Neil Shapiro return SM_IO_EOF;
6340266059SGregory Neil Shapiro }
6440266059SGregory Neil Shapiro
6540266059SGregory Neil Shapiro SM_CONVERT_TIME(fp, fd, timeout, &to);
6640266059SGregory Neil Shapiro
6740266059SGregory Neil Shapiro /* Now do the flush */
6840266059SGregory Neil Shapiro return sm_flush(fp, (int *) &timeout);
6940266059SGregory Neil Shapiro }
7040266059SGregory Neil Shapiro
7140266059SGregory Neil Shapiro /*
7240266059SGregory Neil Shapiro ** SM_FLUSH -- perform the actual flush
7340266059SGregory Neil Shapiro **
7440266059SGregory Neil Shapiro ** Assumes that 'fp' has been validated before this function called.
7540266059SGregory Neil Shapiro **
7640266059SGregory Neil Shapiro ** Parameters:
7740266059SGregory Neil Shapiro ** fp -- file pointer to be flushed
7840266059SGregory Neil Shapiro ** timeout -- max time allowed for flush (milliseconds)
7940266059SGregory Neil Shapiro **
8040266059SGregory Neil Shapiro ** Results:
8140266059SGregory Neil Shapiro ** Success: 0 (zero)
8240266059SGregory Neil Shapiro ** Failure: SM_IO_EOF and errno set
8340266059SGregory Neil Shapiro **
8440266059SGregory Neil Shapiro ** Side Effects:
8540266059SGregory Neil Shapiro ** timeout will get updated with the time remaining (if any)
8640266059SGregory Neil Shapiro */
8740266059SGregory Neil Shapiro
8840266059SGregory Neil Shapiro int
sm_flush(fp,timeout)8940266059SGregory Neil Shapiro sm_flush(fp, timeout)
9040266059SGregory Neil Shapiro register SM_FILE_T *fp;
9140266059SGregory Neil Shapiro int *timeout;
9240266059SGregory Neil Shapiro {
9340266059SGregory Neil Shapiro register unsigned char *p;
9440266059SGregory Neil Shapiro register int n, t;
9540266059SGregory Neil Shapiro int fd;
9640266059SGregory Neil Shapiro
9740266059SGregory Neil Shapiro SM_REQUIRE_ISA(fp, SmFileMagic);
9840266059SGregory Neil Shapiro
9940266059SGregory Neil Shapiro t = fp->f_flags;
10040266059SGregory Neil Shapiro if ((t & SMWR) == 0)
10140266059SGregory Neil Shapiro return 0;
10240266059SGregory Neil Shapiro
10340266059SGregory Neil Shapiro if (t & SMSTR)
10440266059SGregory Neil Shapiro {
10540266059SGregory Neil Shapiro *fp->f_p = '\0';
10640266059SGregory Neil Shapiro return 0;
10740266059SGregory Neil Shapiro }
10840266059SGregory Neil Shapiro
10940266059SGregory Neil Shapiro if ((p = fp->f_bf.smb_base) == NULL)
11040266059SGregory Neil Shapiro return 0;
11140266059SGregory Neil Shapiro
11240266059SGregory Neil Shapiro n = fp->f_p - p; /* write this much */
11340266059SGregory Neil Shapiro
11440266059SGregory Neil Shapiro if ((fd = sm_io_getinfo(fp, SM_IO_WHAT_FD, NULL)) == -1)
11540266059SGregory Neil Shapiro {
11640266059SGregory Neil Shapiro /* can't get an fd, likely internal 'fake' fp */
11740266059SGregory Neil Shapiro errno = 0;
11840266059SGregory Neil Shapiro fd = -1;
11940266059SGregory Neil Shapiro }
12040266059SGregory Neil Shapiro
12140266059SGregory Neil Shapiro /*
12240266059SGregory Neil Shapiro ** Set these immediately to avoid problems with longjmp and to allow
12340266059SGregory Neil Shapiro ** exchange buffering (via setvbuf) in user write function.
12440266059SGregory Neil Shapiro */
12540266059SGregory Neil Shapiro
12640266059SGregory Neil Shapiro fp->f_p = p;
12740266059SGregory Neil Shapiro fp->f_w = t & (SMLBF|SMNBF) ? 0 : fp->f_bf.smb_size; /* implies SMFBF */
12840266059SGregory Neil Shapiro
12940266059SGregory Neil Shapiro for (; n > 0; n -= t, p += t)
13040266059SGregory Neil Shapiro {
13140266059SGregory Neil Shapiro errno = 0; /* needed to ensure EOF correctly found */
13240266059SGregory Neil Shapiro
13340266059SGregory Neil Shapiro /* Call the file type's write function */
13440266059SGregory Neil Shapiro t = (*fp->f_write)(fp, (char *)p, n);
13540266059SGregory Neil Shapiro if (t <= 0)
13640266059SGregory Neil Shapiro {
13740266059SGregory Neil Shapiro if (t == 0 && errno == 0)
13840266059SGregory Neil Shapiro break; /* EOF found */
13940266059SGregory Neil Shapiro
14040266059SGregory Neil Shapiro if (IS_IO_ERROR(fd, t, *timeout))
14140266059SGregory Neil Shapiro {
14240266059SGregory Neil Shapiro fp->f_flags |= SMERR;
14340266059SGregory Neil Shapiro
14440266059SGregory Neil Shapiro /* errno set by fp->f_write */
14540266059SGregory Neil Shapiro return SM_IO_EOF;
14640266059SGregory Neil Shapiro }
14740266059SGregory Neil Shapiro SM_IO_WR_TIMEOUT(fp, fd, *timeout);
1484e4196cbSGregory Neil Shapiro t = 0;
14940266059SGregory Neil Shapiro }
15040266059SGregory Neil Shapiro }
15140266059SGregory Neil Shapiro return 0;
15240266059SGregory Neil Shapiro }
153