1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
20 * *
21 ***********************************************************************/
22 #include "sfhdr.h"
23
24 /* Write data out to the file system
25 **
26 ** Written by Kiem-Phong Vo.
27 */
28
29 #if __STD_C
sfwrite(Sfio_t * f,const Void_t * buf,size_t n)30 ssize_t sfwrite(Sfio_t* f, const Void_t* buf, size_t n)
31 #else
32 ssize_t sfwrite(f,buf,n)
33 Sfio_t* f; /* write to this stream. */
34 Void_t* buf; /* buffer to be written. */
35 size_t n; /* number of bytes. */
36 #endif
37 {
38 reg uchar *s, *begs, *next;
39 reg ssize_t w;
40 reg int local;
41 SFMTXDECL(f);
42
43 SFMTXENTER(f, (ssize_t)(-1));
44
45 GETLOCAL(f,local);
46
47 if(!buf)
48 SFMTXRETURN(f, (ssize_t)(n == 0 ? 0 : -1) );
49
50 /* release peek lock */
51 if(f->mode&SF_PEEK)
52 { if(!(f->mode&SF_WRITE) && (f->flags&SF_RDWR) != SF_RDWR)
53 SFMTXRETURN(f, (ssize_t)(-1));
54
55 if((uchar*)buf != f->next &&
56 (!f->rsrv || f->rsrv->data != (uchar*)buf) )
57 SFMTXRETURN(f, (ssize_t)(-1));
58
59 f->mode &= ~SF_PEEK;
60
61 if(f->mode&SF_PKRD)
62 { /* read past peeked data */
63 char buf[16];
64 reg ssize_t r;
65
66 for(w = n; w > 0; )
67 { if((r = w) > sizeof(buf))
68 r = sizeof(buf);
69 if((r = sysreadf(f->file,buf,r)) <= 0)
70 { n -= w;
71 break;
72 }
73 else w -= r;
74 }
75
76 f->mode &= ~SF_PKRD;
77 f->endb = f->data + n;
78 f->here += n;
79 }
80
81 if((f->mode&SF_READ) && f->proc)
82 f->next += n;
83 }
84
85 s = begs = (uchar*)buf;
86 for(;; f->mode &= ~SF_LOCK)
87 { /* check stream mode */
88 if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0 )
89 { w = s > begs ? s-begs : -1;
90 SFMTXRETURN(f,w);
91 }
92
93 SFLOCK(f,local);
94
95 w = f->endb - f->next;
96
97 if(s == f->next) /* after sfreserve */
98 { if(w > (ssize_t)n)
99 w = (ssize_t)n;
100 f->next = (s += w);
101 n -= w;
102 break;
103 }
104
105 /* attempt to create space in buffer */
106 if(w == 0 || ((f->flags&SF_WHOLE) && w < (ssize_t)n) )
107 { if(f->flags&SF_STRING) /* extend buffer */
108 { (void)SFWR(f, s, n-w, f->disc);
109 if((w = f->endb - f->next) < (ssize_t)n)
110 { if(!(f->flags&SF_STRING)) /* maybe sftmp */
111 { if(f->next > f->data)
112 goto fls_buf;
113 }
114 else if(w == 0)
115 break;
116 }
117 }
118 else if(f->next > f->data)
119 { fls_buf:
120 (void)SFFLSBUF(f, -1);
121 if((w = f->endb - f->next) < (ssize_t)n &&
122 (f->flags&SF_WHOLE) && f->next > f->data )
123 break;
124 }
125 }
126
127 if(!(f->flags&SF_STRING) && f->next == f->data &&
128 (((f->flags&SF_WHOLE) && w <= n) || SFDIRECT(f,n)) )
129 { /* bypass buffering */
130 if((w = SFWR(f,s,n,f->disc)) <= 0 )
131 break;
132 }
133 else
134 { if(w > (ssize_t)n)
135 w = (ssize_t)n;
136 if(w <= 0) /* no forward progress possible */
137 break;
138 memcpy(f->next, s, w);
139 f->next += w;
140 }
141
142 s += w;
143 if((n -= w) <= 0)
144 break;
145 }
146
147 /* always flush buffer for share streams */
148 if(f->extent < 0 && (f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC) )
149 (void)SFFLSBUF(f,-1);
150
151 /* check to see if buffer should be flushed */
152 else if(n == 0 && (f->flags&SF_LINE) && !(f->flags&SF_STRING))
153 { if((ssize_t)(n = f->next-f->data) > (w = s-begs))
154 n = w;
155 if(n > 0 && n < HIFORLINE)
156 { for(next = f->next-1; n > 0; --n, --next)
157 { if(*next == '\n')
158 { n = HIFORLINE;
159 break;
160 }
161 }
162 }
163 if(n >= HIFORLINE)
164 (void)SFFLSBUF(f,-1);
165 }
166
167 SFOPEN(f,local);
168
169 w = s-begs;
170 SFMTXRETURN(f,w);
171 }
172