source: trunk/third/sendmail/libsm/wbuf.c @ 19204

Revision 19204, 2.5 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19203, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 *      All rights reserved.
4 * Copyright (c) 1990, 1993
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Chris Torek.
9 *
10 * By using this file, you agree to the terms and conditions set
11 * forth in the LICENSE file which can be found at the top level of
12 * the sendmail distribution.
13 */
14
15#include <sm/gen.h>
16SM_RCSID("@(#)$Id: wbuf.c,v 1.1.1.1 2003-04-08 15:06:05 zacheiss Exp $")
17#include <errno.h>
18#include <sm/io.h>
19#include "local.h"
20
21/* Note: This function is called from a macro located in <sm/io.h> */
22
23/*
24**  SM_WBUF -- write character to and flush (likely now full) buffer
25**
26**  Write the given character into the (probably full) buffer for
27**  the given file.  Flush the buffer out if it is or becomes full,
28**  or if c=='\n' and the file is line buffered.
29**
30**      Parameters:
31**              fp -- the file pointer
32**              timeout -- time to complete operation (milliseconds)
33**              c -- int representation of the character to add
34**
35**      Results:
36**              Failure: -1 and sets errno
37**              Success: int value of 'c'
38*/
39
40int
41sm_wbuf(fp, timeout, c)
42        register SM_FILE_T *fp;
43        int timeout;
44        register int c;
45{
46        register int n;
47
48        /*
49        **  In case we cannot write, or longjmp takes us out early,
50        **  make sure w is 0 (if fully- or un-buffered) or -bf.smb_size
51        **  (if line buffered) so that we will get called again.
52        **  If we did not do this, a sufficient number of sm_io_putc()
53        **  calls might wrap w from negative to positive.
54        */
55
56        fp->f_w = fp->f_lbfsize;
57        if (cantwrite(fp))
58        {
59                errno = EBADF;
60                return SM_IO_EOF;
61        }
62        c = (unsigned char)c;
63
64        /*
65        **  If it is completely full, flush it out.  Then, in any case,
66        **  stuff c into the buffer.  If this causes the buffer to fill
67        **  completely, or if c is '\n' and the file is line buffered,
68        **  flush it (perhaps a second time).  The second flush will always
69        **  happen on unbuffered streams, where bf.smb_size==1; sm_io_flush()
70        **  guarantees that sm_io_putc() will always call sm_wbuf() by setting
71        **  w to 0, so we need not do anything else.
72        **  Note for the timeout, only one of the sm_io_flush's will get called.
73        */
74
75        n = fp->f_p - fp->f_bf.smb_base;
76        if (n >= fp->f_bf.smb_size)
77        {
78                if (sm_io_flush(fp, timeout))
79                        return SM_IO_EOF; /* sm_io_flush() sets errno */
80                n = 0;
81        }
82        fp->f_w--;
83        *fp->f_p++ = c;
84        if (++n == fp->f_bf.smb_size || (fp->f_flags & SMLBF && c == '\n'))
85                if (sm_io_flush(fp, timeout))
86                        return SM_IO_EOF; /* sm_io_flush() sets errno */
87        return c;
88}
Note: See TracBrowser for help on using the repository browser.