Subversion Repositories Kolibri OS

Rev

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 <>.  It
43
	This is a reentrant version of <>.  It
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;