Subversion Repositories Kolibri OS

Rev

Rev 6330 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4921 Serge 1
/* write.c -- write bytes to an output device.
2
 *
3
 * Copyright (c) 1995 Cygnus Support
4
 *
5
 * The authors hereby grant permission to use, copy, modify, distribute,
6
 * and license this software and its documentation for any purpose, provided
7
 * that existing copyright notices are retained in all copies and that this
8
 * notice is included verbatim in any distributions. No written agreement,
9
 * license, or royalty fee is required for any of the authorized uses.
10
 * Modifications to this software may be copyrighted by their authors
11
 * and need not follow the licensing terms described here, provided that
12
 * the new terms are clearly indicated on the first page of each file where
13
 * they apply.
14
 */
15
#include 
6536 serge 16
#include 
4921 Serge 17
#include 
4349 Serge 18
#include 
4921 Serge 19
#include "io.h"
4349 Serge 20
 
4921 Serge 21
#undef erro
22
extern int errno;
23
 
24
 
25
#if 0
26
#define PAD_SIZE 512
27
 
28
static int zero_pad(int handle )           /* 09-jan-95 */
29
/*******************************/
4349 Serge 30
{
4921 Serge 31
    int         rc;
32
    long        curPos, eodPos;
33
    long        bytesToWrite;
34
    unsigned    writeAmt;
35
    char        zeroBuf[PAD_SIZE];
36
 
37
    // Pad with zeros due to lseek() past EOF (POSIX)
38
    curPos = lseek( handle, 0L, SEEK_CUR );   /* current offset */
39
    if( curPos == -1 )
40
        return( -1 );
41
    eodPos = lseek( handle, 0L, SEEK_END );   /* end of data offset */
42
    if( eodPos == -1 )
43
        return( -1 );
44
 
45
    if( curPos > eodPos ) {
46
        bytesToWrite = curPos - eodPos;         /* amount to pad by */
47
 
48
        if( bytesToWrite > 0 ) {                /* only write if needed */
49
            memset( zeroBuf, 0x00, PAD_SIZE );  /* zero out a buffer */
50
            do {                                /* loop until done */
51
                if( bytesToWrite > PAD_SIZE )
52
                    writeAmt = 512;
53
                else
54
                    writeAmt = (unsigned)bytesToWrite;
55
                rc = _write_r(ptr, handle, zeroBuf, writeAmt );
56
                if( rc < 0 )
57
                    return( rc );
58
                bytesToWrite -= writeAmt;       /* more bytes written */
59
            } while( bytesToWrite != 0 );
60
        }
61
    } else {
62
        curPos = _lseek_r( ptr, handle, curPos, SEEK_SET );
63
        if( curPos == -1 ) {
64
            return( -1 );
65
        }
66
    }
67
 
68
    return( 0 );                /* return success code */
69
}
70
#endif
71
 
72
static int os_write(int handle, const void *buffer, unsigned len, unsigned *amt )
73
{
74
    __io_handle *ioh;
75
    int          rc;
76
 
77
    rc   = 0;
78
    *amt = 0;
79
 
80
    ioh = &__io_tab[handle];
81
 
82
    rc = ioh->write(ioh->name,(const void*)buffer,ioh->offset,len,amt);
83
 
84
    ioh->offset+= *amt;
85
 
6330 serge 86
    if( *amt && *amt != len )
4921 Serge 87
    {
88
        rc = ENOSPC;
6330 serge 89
        errno = rc;
4921 Serge 90
    }
91
 
92
    return( rc );
93
}
94
 
95
/*
96
 * write -- write bytes to the serial port. Ignore fd, since
97
 *          stdout and stderr are the same. Since we have no filesystem,
98
 *          open will only return an error.
99
 */
100
ssize_t write(int fd, const void *buffer, size_t cnt)
101
{
102
    _ssize_t      ret;
103
    unsigned int  iomode_flags;
104
    unsigned      len_written, i, j;
105
    int           rc2;
106
    char         *buf;
107
 
108
    __io_handle  *ioh;
109
 
110
    if( (fd < 0) || (fd >=64) )
111
    {
112
        errno = EBADF;
113
        return -1;
114
    };
115
 
116
    ioh = &__io_tab[fd];
117
 
118
    iomode_flags = ioh->mode;
119
 
120
    if( iomode_flags == 0 )
121
    {
122
        errno = EBADF;
123
        return( -1 );
124
    }
125
 
126
    if( !(iomode_flags & _WRITE) )
127
    {
128
        errno = EACCES ;
129
        return( -1 );
130
    }
131
 
132
    if( (iomode_flags & _APPEND) && !(iomode_flags & _ISTTY) )
133
    {
134
        ioh->offset = lseek(fd, 0L, SEEK_END );   /* end of data offset */
135
    }
136
 
137
    len_written = 0;
138
    rc2 = 0;
139
 
140
    // Pad the file with zeros if necessary
141
    if( iomode_flags & _FILEEXT )
142
    {
143
        // turn off file extended flag
144
        ioh->mode = iomode_flags & (~_FILEEXT);
145
 
146
        // It is not required to pad a file with zeroes on an NTFS file system;
147
        // unfortunately it is required on FAT (and probably FAT32). (JBS)
148
//        rc2 = zero_pad( ptr, fd );
149
    }
150
 
151
    if( rc2 == 0 )
152
    {
153
        if( iomode_flags & _BINARY ) {  /* if binary mode */
154
            rc2 = os_write(fd, buffer, cnt, &len_written );
155
            /* end of binary mode part */
156
        } else {    /* text mode */
157
 
158
            int buf_size = 512;
159
 
160
            buf = (char*)alloca( buf_size );
161
 
162
            j = 0;
163
            for( i = 0; i < cnt; )
164
            {
165
                if( ((const char*)buffer)[i] == '\n' )
166
                {
167
                    buf[j] = '\r';
168
                    ++j;
169
                    if( j == buf_size )
170
                    {
171
                        rc2 = os_write(fd, buf, buf_size, &j );
172
                        if( rc2 == -1 )
173
                            break;
174
                        len_written += j;
175
                        if( rc2 == ENOSPC )
176
                            break;
177
                        len_written = i;
178
                        j = 0;
179
                    }
180
                }
181
                buf[j] = ((const char*)buffer)[i];
182
                ++i;
183
                ++j;
184
                if( j == buf_size ) {
185
                    rc2 = os_write(fd, buf, buf_size, &j );
186
                    if( rc2 == -1 )
187
                        break;
188
                    len_written += j;
189
                    if( rc2 == ENOSPC )
190
                        break;
191
                    len_written = i;
192
                    j = 0;
193
                }
194
            }
195
            if( j ) {
196
                rc2 = os_write(fd, buf, j, &i );
197
                if( rc2 == ENOSPC ) {
198
                    len_written += i;
199
                } else {
200
                    len_written = cnt;
201
                }
202
            }
203
            /* end of text mode part */
204
        }
205
    }
206
 
207
    if( rc2 == -1 ) {
208
        return( rc2 );
209
    } else {
210
        return( len_written );
211
    }
212
 
213
  return 0;
214
}
215