Subversion Repositories Kolibri OS

Rev

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