Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
550 serge 1
/****************************************************************************
2
*
3
*                            Open Watcom Project
4
*
5
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6
*
7
*  ========================================================================
8
*
9
*    This file contains Original Code and/or Modifications of Original
10
*    Code as defined in and that are subject to the Sybase Open Watcom
11
*    Public License version 1.0 (the 'License'). You may not use this file
12
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14
*    provided with the Original Code and Modifications, and is also
15
*    available at www.sybase.com/developer/opensource.
16
*
17
*    The Original Code and all software distributed under the License are
18
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22
*    NON-INFRINGEMENT. Please see the License for the specific language
23
*    governing rights and limitations under the License.
24
*
25
*  ========================================================================
26
*
27
* Description:  Platform independent fwrite() implementation.
28
*
29
****************************************************************************/
30
 
31
 
32
#include "variety.h"
33
#include 
34
#include 
35
#include 
36
#include 
37
#include "fileacc.h"
38
#include "rtdata.h"
39
#include "seterrno.h"
40
#include "qwrite.h"
41
#include "flush.h"
42
#include "streamio.h"
43
 
44
 
45
_WCRTLINK size_t fwrite( const void *buf, size_t size, size_t n, FILE *fp )
46
{
47
    size_t      count;
48
    unsigned    oflag;
49
 
50
    _ValidFile( fp, 0 );
51
    _AccessFile( fp );
52
    if( (fp->_flag & _WRITE) == 0 ) {
53
        __set_errno( EBADF );
54
        fp->_flag |= _SFERR;
55
        _ReleaseFile( fp );
56
        return( 0 );        /* POSIX says return 0 */
57
    }
58
    n *= size;
59
    if( n == 0 ) {
60
        _ReleaseFile( fp );
61
        return( n );
62
    }
63
    if( _FP_BASE(fp) == NULL ) {
64
        __ioalloc( fp );                    /* allocate buffer */
65
    }
66
    oflag = fp->_flag & (_SFERR | _EOF);    /* JBS 27-jan-92 */
67
    fp->_flag &= ~(_SFERR | _EOF);          /* JBS 27-jan-92 */
68
    count = 0;
69
#if !defined( __UNIX__ )
70
    if( fp->_flag & _BINARY ) {             /* binary I/O */
71
#else
72
    {
73
#endif
74
        size_t  bytes_left = n, bytes;
75
 
76
        do {
77
            /* if our buffer is empty, and user's buffer is larger,
78
               then write directly from user's buffer.  28-apr-90 */
79
 
80
            if( fp->_cnt == 0  &&  bytes_left >= fp->_bufsize ) {
81
                bytes = bytes_left & -512;          /* multiple of 512 */
82
                if( bytes == 0 ) {
83
                    bytes = bytes_left;             /* bufsize < 512   */
84
                }
85
                n = __qwrite( fileno( fp ), buf, bytes );
86
                if( n == -1 ) {
87
                    fp->_flag |= _SFERR;
88
                }
89
#if !defined( __UNIX__ )
90
                else if( n == 0 ) {
91
                    _RWD_errno = ENOSPC;
92
                    fp->_flag |= _SFERR;
93
                }
94
#endif
95
                bytes = n;
96
            } else {
97
                bytes = fp->_bufsize - fp->_cnt;
98
                if( bytes > bytes_left ) {
99
                    bytes = bytes_left;
100
                }
101
                memcpy( fp->_ptr, buf, bytes );
102
                fp->_ptr += bytes;
103
                fp->_cnt += bytes;
104
                fp->_flag |= _DIRTY;
105
                if( (fp->_cnt == fp->_bufsize) || (fp->_flag & _IONBF) ) {
106
                    __flush(fp);
107
                }
108
            }
109
            buf = ((const char *)buf) + bytes;
110
            count += bytes;
111
            bytes_left -= bytes;
112
        } while( bytes_left && !ferror( fp ) );
113
#if !defined( __UNIX__ )
114
    } else {        /* text I/O */
115
        const char      *bufptr;
116
        int             not_buffered;
117
    #ifndef __NETWARE__
118
        int             old_orientation;
119
    #endif
120
        /* temporarily enable buffering saving the previous setting */
121
        not_buffered = 0;
122
        if( fp->_flag & _IONBF ) {
123
            not_buffered = 1;
124
            fp->_flag &= ~_IONBF;
125
            fp->_flag |= _IOFBF;
126
        }
127
 
128
        /*** Use fputc, and make it think the stream is byte-oriented ***/
129
    #ifndef __NETWARE__
130
        old_orientation = _FP_ORIENTATION(fp);
131
        _FP_ORIENTATION(fp) = _BYTE_ORIENTED;
132
    #endif
133
        bufptr = (const char *)buf;
134
        do {
135
            fputc( *(bufptr++), fp );
136
            if( fp->_flag & (_EOF | _SFERR) ) break;
137
            ++count;
138
        } while( count != n );
139
    #ifndef __NETWARE__
140
        _FP_ORIENTATION(fp) = old_orientation;
141
    #endif
142
 
143
        if( not_buffered ) {        /* if wasn't buffered, then reset */
144
            fp->_flag &= ~_IOFBF;
145
            fp->_flag |= _IONBF;
146
            __flush( fp );
147
        }
148
#endif
149
    }
150
    if( fp->_flag & _SFERR ) {
151
        /*
152
         * Quantum 11-17-92 Temporary buffering confuses the return
153
         *                  value if the call is interrupted.
154
         *                  kludge: return 0 on error
155
         */
156
        count = 0;
157
    }
158
    fp->_flag |= oflag;                     /* JBS 27-jan-92 */
159
    _ReleaseFile( fp );
160
    return( count / size );
161
}