Rev 4874 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4874 | Rev 4921 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* Reentrant versions of write system call. */ |
1 | /* Reentrant versions of write system call. */ |
Line 2... | Line 2... | ||
2 | 2 | ||
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include <_syslist.h> |
- | |
6 | #include |
- | |
7 | #include |
- | |
8 | #include |
- | |
Line 9... | Line 5... | ||
9 | 5 | #include <_syslist.h> |
|
10 | 6 | ||
Line 11... | Line 7... | ||
11 | /* Some targets provides their own versions of this functions. Those |
7 | /* Some targets provides their own versions of this functions. Those |
Line 18... | Line 14... | ||
18 | #endif |
14 | #endif |
Line 19... | Line 15... | ||
19 | 15 | ||
Line 20... | Line 16... | ||
20 | #ifndef REENTRANT_SYSCALLS_PROVIDED |
16 | #ifndef REENTRANT_SYSCALLS_PROVIDED |
- | 17 | ||
- | 18 | /* We use the errno variable used by the system dependent layer. */ |
|
Line 21... | Line 19... | ||
21 | 19 | #undef errno |
|
22 | /* We use the errno variable used by the system dependent layer. */ |
20 | extern int errno; |
23 | 21 | ||
Line 45... | Line 43... | ||
45 | This is a reentrant version of < |
43 | This is a reentrant version of < |
46 | takes a pointer to the global data block, which holds |
44 | takes a pointer to the global data block, which holds |
47 | < |
45 | < |
48 | */ |
46 | */ |
Line 49... | Line -... | ||
49 | - | ||
50 | - | ||
51 | #define _WRITE 0x0002 /* file opened for writing */ |
- | |
52 | #define _APPEND 0x0080 /* file opened for append */ |
- | |
53 | #define _BINARY 0x0040 /* file is binary, skip CRLF processing */ |
- | |
54 | #define _ISTTY 0x2000 /* is console device */ |
- | |
55 | #define _FILEEXT 0x8000 /* lseek with positive offset has been done */ |
- | |
56 | - | ||
57 | #define __handle_check( __h, __r ) \ |
- | |
58 | if( (__h) < 0 || (__h) > __NFiles ) { \ |
- | |
59 | ptr->_errno = EBADF; \ |
- | |
60 | return( __r ); \ |
- | |
61 | } |
- | |
62 | - | ||
63 | extern unsigned __NFiles; |
- | |
64 | - | ||
65 | #define PAD_SIZE 512 |
- | |
66 | - | ||
67 | static int zero_pad(struct _reent *ptr, int handle ) /* 09-jan-95 */ |
- | |
68 | /*******************************/ |
- | |
69 | { |
- | |
70 | int rc; |
- | |
71 | long curPos, eodPos; |
- | |
72 | long bytesToWrite; |
- | |
73 | unsigned writeAmt; |
- | |
74 | char zeroBuf[PAD_SIZE]; |
- | |
75 | - | ||
76 | // Pad with zeros due to lseek() past EOF (POSIX) |
- | |
77 | curPos = _lseek_r( ptr, handle, 0L, SEEK_CUR ); /* current offset */ |
- | |
78 | if( curPos == -1 ) |
- | |
79 | return( -1 ); |
- | |
80 | eodPos = _lseek_r( ptr, handle, 0L, SEEK_END ); /* end of data offset */ |
- | |
81 | if( eodPos == -1 ) |
- | |
82 | return( -1 ); |
- | |
83 | - | ||
84 | if( curPos > eodPos ) { |
- | |
85 | bytesToWrite = curPos - eodPos; /* amount to pad by */ |
- | |
86 | - | ||
87 | if( bytesToWrite > 0 ) { /* only write if needed */ |
- | |
88 | memset( zeroBuf, 0x00, PAD_SIZE ); /* zero out a buffer */ |
- | |
89 | do { /* loop until done */ |
- | |
90 | if( bytesToWrite > PAD_SIZE ) |
- | |
91 | writeAmt = 512; |
- | |
92 | else |
- | |
93 | writeAmt = (unsigned)bytesToWrite; |
- | |
94 | rc = _write_r(ptr, handle, zeroBuf, writeAmt ); |
- | |
95 | if( rc < 0 ) |
- | |
96 | return( rc ); |
- | |
97 | bytesToWrite -= writeAmt; /* more bytes written */ |
- | |
98 | } while( bytesToWrite != 0 ); |
- | |
99 | } |
- | |
100 | } else { |
- | |
101 | curPos = _lseek_r( ptr, handle, curPos, SEEK_SET ); |
- | |
102 | if( curPos == -1 ) { |
- | |
103 | return( -1 ); |
- | |
104 | } |
- | |
105 | } |
- | |
106 | - | ||
107 | return( 0 ); /* return success code */ |
- | |
108 | } |
- | |
109 | - | ||
110 | - | ||
111 | static int os_write(struct _reent *ptr, int handle, |
- | |
112 | const void *buffer, unsigned len, unsigned *amt ) |
- | |
113 | /********************************************************************************/ |
- | |
114 | { |
- | |
115 | __file_handle *fh; |
- | |
116 | int rc; |
- | |
117 | - | ||
118 | rc = 0; |
- | |
119 | *amt = 0; |
- | |
120 | - | ||
121 | fh = (__file_handle*) __getOSHandle( handle ); |
- | |
122 | - | ||
123 | rc = fh->write(fh->name,buffer,fh->offset,len,amt); |
- | |
124 | - | ||
125 | fh->offset+= *amt; |
- | |
126 | - | ||
127 | if( *amt != len ) |
- | |
128 | { |
- | |
129 | rc = ENOSPC; |
- | |
130 | ptr->_errno = ENOSPC; |
- | |
131 | } |
- | |
132 | return( rc ); |
- | |
133 | } |
47 | |
134 | _ssize_t |
48 | _ssize_t |
135 | _DEFUN (_write_r, (ptr, fd, buffer, cnt), |
49 | _DEFUN (_write_r, (ptr, fd, buf, cnt), |
136 | struct _reent *ptr _AND |
50 | struct _reent *ptr _AND |
137 | int fd _AND |
51 | int fd _AND |
138 | _CONST _PTR buffer _AND |
52 | _CONST _PTR buf _AND |
139 | size_t cnt) |
53 | size_t cnt) |
140 | { |
54 | { |
141 | _ssize_t ret; |
- | |
142 | unsigned int iomode_flags; |
- | |
143 | unsigned len_written, i, j; |
- | |
144 | int rc2; |
- | |
145 | char *buf; |
- | |
146 | - | ||
147 | __file_handle *fh; |
- | |
148 | - | ||
149 | __handle_check( fd, -1 ); |
- | |
150 | - | ||
151 | iomode_flags = __GetIOMode( fd ); |
- | |
152 | if( iomode_flags == 0 ) |
- | |
153 | { |
- | |
154 | ptr->_errno = EBADF; |
- | |
155 | return( -1 ); |
- | |
156 | } |
- | |
157 | - | ||
158 | if( !(iomode_flags & _WRITE) ) { |
- | |
159 | ptr->_errno = EACCES ; /* changed from EBADF to EACCES 23-feb-89 */ |
- | |
160 | return( -1 ); |
- | |
161 | } |
- | |
162 | - | ||
163 | if( (iomode_flags & _APPEND) && !(iomode_flags & _ISTTY) ) |
- | |
164 | { |
- | |
165 | fh->offset = _lseek_r(ptr, fd, 0L, SEEK_END ); /* end of data offset */ |
- | |
166 | } |
- | |
167 | - | ||
168 | len_written = 0; |
- | |
169 | rc2 = 0; |
- | |
170 | - | ||
171 | // Pad the file with zeros if necessary |
- | |
172 | if( iomode_flags & _FILEEXT ) |
- | |
173 | { |
- | |
174 | // turn off file extended flag |
- | |
175 | __SetIOMode_nogrow( fd, iomode_flags&(~_FILEEXT) ); |
- | |
176 | - | ||
177 | // It is not required to pad a file with zeroes on an NTFS file system; |
- | |
178 | // unfortunately it is required on FAT (and probably FAT32). (JBS) |
- | |
179 | rc2 = zero_pad( ptr, fd ); |
- | |
180 | } |
- | |
181 | - | ||
182 | if( rc2 == 0 ) |
- | |
183 | { |
- | |
184 | if( iomode_flags & _BINARY ) { /* if binary mode */ |
- | |
185 | rc2 = os_write(ptr, fd, buffer, cnt, &len_written ); |
- | |
186 | /* end of binary mode part */ |
- | |
187 | } else { /* text mode */ |
- | |
188 | - | ||
189 | int buf_size = 512; |
- | |
190 | - | ||
191 | buf = (char*)alloca( buf_size ); |
- | |
192 | - | ||
193 | j = 0; |
- | |
194 | for( i = 0; i < cnt; ) |
- | |
195 | { |
- | |
196 | if( ((const char*)buffer)[i] == '\n' ) |
- | |
197 | { |
- | |
198 | buf[j] = '\r'; |
- | |
199 | ++j; |
- | |
200 | if( j == buf_size ) |
- | |
201 | { |
- | |
202 | rc2 = os_write(ptr, fd, buf, buf_size, &j ); |
- | |
203 | if( rc2 == -1 ) |
- | |
204 | break; |
- | |
205 | len_written += j; |
- | |
206 | if( rc2 == ENOSPC ) |
- | |
207 | break; |
- | |
208 | len_written = i; |
- | |
209 | j = 0; |
- | |
210 | } |
- | |
211 | } |
- | |
212 | buf[j] = ((const char*)buffer)[i]; |
- | |
213 | ++i; |
- | |
214 | ++j; |
- | |
215 | if( j == buf_size ) { |
- | |
216 | rc2 = os_write(ptr, fd, buf, buf_size, &j ); |
- | |
217 | if( rc2 == -1 ) |
- | |
218 | break; |
- | |
219 | len_written += j; |
- | |
220 | if( rc2 == ENOSPC ) |
- | |
221 | break; |
- | |
222 | len_written = i; |
- | |
223 | j = 0; |
- | |
224 | } |
- | |
225 | } |
- | |
226 | if( j ) { |
- | |
227 | rc2 = os_write(ptr, fd, buf, j, &i ); |
- | |
228 | if( rc2 == ENOSPC ) { |
- | |
229 | len_written += i; |
- | |
230 | } else { |
- | |
231 | len_written = cnt; |
- | |
232 | } |
- | |
233 | } |
- | |
234 | /* end of text mode part */ |
- | |
235 | } |
- | |
236 | } |
- | |
237 | - | ||
238 | if( rc2 == -1 ) { |
- | |
239 | return( rc2 ); |
- | |
240 | } else { |
- | |
241 | return( len_written ); |
- | |
242 | } |
- | |
243 | } |
- | |
244 | - | ||
245 | _ssize_t |
- | |
246 | _DEFUN (write, ( fd, buffer, cnt), |
- | |
247 | int fd _AND |
- | |
248 | _CONST _PTR buffer _AND |
- | |
249 | size_t cnt) |
- | |
250 | - | ||
251 | { |
- | |
252 | - | ||
Line -... | Line 55... | ||
- | 55 | _ssize_t ret; |
|
- | 56 | ||
- | 57 | errno = 0; |
|
- | 58 | if ((ret = (_ssize_t)_write (fd, buf, cnt)) == -1 && errno != 0) |
|
253 | return _write_r(_REENT, fd, buffer, cnt); |
59 | ptr->_errno = errno; |
Line 254... | Line 60... | ||
254 | 60 | return ret; |