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

Revision 19204, 3.4 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: makebuf.c,v 1.1.1.1 2003-04-08 15:06:29 zacheiss Exp $")
17#include <stdlib.h>
18#include <unistd.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <sm/io.h>
22#include <sm/heap.h>
23#include <sm/conf.h>
24#include "local.h"
25
26/*
27**  SM_MAKEBUF -- make a buffer for the file
28**
29**      Parameters:
30**              fp -- the file to be buffered
31**
32**      Returns:
33**              nothing
34**
35**      Allocate a file buffer, or switch to unbuffered I/O.
36**      By default tty devices default to line buffered.
37*/
38
39void
40sm_makebuf(fp)
41        register SM_FILE_T *fp;
42{
43        register void *p;
44        register int flags;
45        size_t size;
46        int couldbetty;
47
48        if (fp->f_flags & SMNBF)
49        {
50                fp->f_bf.smb_base = fp->f_p = fp->f_nbuf;
51                fp->f_bf.smb_size = 1;
52                return;
53        }
54        flags = sm_whatbuf(fp, &size, &couldbetty);
55        if ((p = sm_malloc(size)) == NULL)
56        {
57                fp->f_flags |= SMNBF;
58                fp->f_bf.smb_base = fp->f_p = fp->f_nbuf;
59                fp->f_bf.smb_size = 1;
60                return;
61        }
62        if (!Sm_IO_DidInit)
63                sm_init();
64        flags |= SMMBF;
65        fp->f_bf.smb_base = fp->f_p = p;
66        fp->f_bf.smb_size = size;
67        if (couldbetty && isatty(fp->f_file))
68                flags |= SMLBF;
69        fp->f_flags |= flags;
70}
71
72/*
73**  SM_WHATBUF -- determine proper buffer for a file (internal)
74**
75**  Plus it fills in 'bufsize' for recommended buffer size and
76**  fills in flag to indicate if 'fp' could be a tty (nothing
77**  to do with "betty" :-) ).
78**
79**      Parameters:
80**              fp -- file pointer to be buffered
81**              bufsize -- new buffer size (a return)
82**              couldbetty -- could be a tty (returns)
83**
84**      Returns:
85**              Success:
86**              on error:
87**                      SMNPT -- not seek opimized
88**                      SMOPT -- seek opimized
89*/
90
91int
92sm_whatbuf(fp, bufsize, couldbetty)
93        register SM_FILE_T *fp;
94        size_t *bufsize;
95        int *couldbetty;
96{
97        struct stat st;
98
99        if (fp->f_file < 0 || fstat(fp->f_file, &st) < 0)
100        {
101                *couldbetty = 0;
102                *bufsize = SM_IO_BUFSIZ;
103                return SMNPT;
104        }
105
106        /* could be a tty iff it is a character device */
107        *couldbetty = S_ISCHR(st.st_mode);
108        if (st.st_blksize == 0)
109        {
110                *bufsize = SM_IO_BUFSIZ;
111                return SMNPT;
112        }
113
114#if SM_IO_MAX_BUF_FILE > 0
115        if (S_ISREG(st.st_mode) && st.st_blksize > SM_IO_MAX_BUF_FILE)
116                st.st_blksize = SM_IO_MAX_BUF_FILE;
117#endif /* SM_IO_MAX_BUF_FILE > 0 */
118
119#if SM_IO_MAX_BUF > 0 || SM_IO_MIN_BUF > 0
120        if (!S_ISREG(st.st_mode))
121        {
122# if SM_IO_MAX_BUF > 0
123                if (st.st_blksize > SM_IO_MAX_BUF)
124                        st.st_blksize = SM_IO_MAX_BUF;
125#  if SM_IO_MIN_BUF > 0
126                else
127#  endif /* SM_IO_MIN_BUF > 0 */
128# endif /* SM_IO_MAX_BUF > 0 */
129# if SM_IO_MIN_BUF > 0
130                if (st.st_blksize < SM_IO_MIN_BUF)
131                        st.st_blksize = SM_IO_MIN_BUF;
132# endif /* SM_IO_MIN_BUF > 0 */
133        }
134#endif /* SM_IO_MAX_BUF > 0 || SM_IO_MIN_BUF > 0 */
135
136        /*
137        **  Optimise fseek() only if it is a regular file.  (The test for
138        **  sm_std_seek is mainly paranoia.)  It is safe to set _blksize
139        **  unconditionally; it will only be used if SMOPT is also set.
140        */
141
142        if ((fp->f_flags & SMSTR) == 0)
143        {
144                *bufsize = st.st_blksize;
145                fp->f_blksize = st.st_blksize;
146        }
147        else
148                *bufsize = SM_IO_BUFSIZ;
149        if ((st.st_mode & S_IFMT) == S_IFREG &&
150            fp->f_seek == sm_stdseek)
151                return SMOPT;
152        else
153                return SMNPT;
154}
Note: See TracBrowser for help on using the repository browser.