File: iob_flush.c

package info (click to toggle)
fis-gtm 6.3-014-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 36,680 kB
  • sloc: ansic: 333,039; asm: 5,180; csh: 4,956; sh: 1,924; awk: 291; makefile: 66; sed: 13
file content (109 lines) | stat: -rwxr-xr-x 2,589 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/****************************************************************
 *								*
 *	Copyright 2001, 2009 Fidelity Information Services, Inc	*
 *								*
 *	This source code contains the intellectual property	*
 *	of its copyright holder(s), and is made available	*
 *	under a license.  If you do not know the terms of	*
 *	the license, please stop and do not read further.	*
 *								*
 ****************************************************************/

/* iob_flush - buffered I/O with GT.M error signaling

   flush I/O buffer.  No action is taken if the last operation was not a
   write.

   void iob_flush(BFILE *bf)

   BFILE *bf:	file to flush

   Note:  It is assumed that the write buffer is full.  Exactly one
   	  record of size bf->bufsiz is written.

*/
#include "mdef.h"

#include "gtm_string.h"

#include <errno.h>
#include "gtm_fcntl.h"
#include "gtm_unistd.h"
#include "gtm_stdio.h"
#include "gtm_stat.h"

#include "error.h"
#include "iob.h"
#include "gtmio.h"

void iob_flush(BFILE *bf)
{
	ssize_t	nwritten, nrewritten;
	ssize_t	nbytes;
	int	rc;

	error_def(ERR_IOEOF);

	if (!bf->write_mode)
		return;

	if (bf->remaining == bf->bufsiz)	/* return if nothing to write */
		return;

	if (bf->remaining)			/* set remaining bytes to null */
	{
		memset(bf->bptr, 0, bf->remaining);
		/* bytes to transfer, rounded up to the nearest block */
		nbytes = (((bf->bptr - bf->buf) + bf->blksiz - 1) / bf->blksiz)
			* bf->blksiz;
	}
	else
		nbytes = bf->bufsiz;

	DOWRITERL(bf->fd, bf->buf, nbytes, nwritten);
#ifdef DEBUG_IOB
	PRINTF("iob_flush:\t\twrite(%d, %x, %d) = %d\n",bf->fd,bf->buf,nbytes,nwritten);
#endif
	bf->bptr = bf->buf;
	bf->remaining = bf->bufsiz;

	if (nwritten < nbytes)
	{
		CLOSEFILE_RESET(bf->fd, rc);	/* resets "bf->fd" to FD_INVALID */
#ifdef SCO
		if (nwritten == -1)
		{
			if  (errno == ENXIO)
				nwritten = 0;
			else
			{
				rts_error(VARLSTCNT(1) errno);
				return;
			}
		}
#else
		if (nwritten == -1)
		{
			rts_error(VARLSTCNT(1) errno);
			return;
		}
#endif
		rts_error(VARLSTCNT(1) ERR_IOEOF);
		/* if we continued from here, assume that this is a magnetic
		   tape and we have loaded the next volume. Re-open and
		   finish the write operation.
		   */
		while (FD_INVALID == (bf->fd = OPEN3(bf->path,bf->oflag,bf->mode)))
			rts_error(VARLSTCNT(1) errno);
		DOWRITERL(bf->fd, bf->buf + nwritten, nbytes - nwritten, nrewritten);
#ifdef DEBUG_IOB
		PRINTF("iob_flush:\t\twrite(%d, %x, %d) = %d\n", bf->fd, bf->buf, nbytes, nwritten);
#endif
		if (nrewritten < nbytes - nwritten)
		{
			rts_error(VARLSTCNT(1) errno);
			return;
		}
	}
}