Subversion Repositories Kolibri OS

Rev

Rev 4921 | Rev 6536 | 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
 
6330 serge 89
    if( *amt && *amt != len )
4921 Serge 90
    {
91
        rc = ENOSPC;
6330 serge 92
        errno = rc;
4921 Serge 93
    }
94
 
95
    return( rc );
96
}
97
 
98
/*
99
 * write -- write bytes to the serial port. Ignore fd, since
100
 *          stdout and stderr are the same. Since we have no filesystem,
101
 *          open will only return an error.
102
 */
103
ssize_t write(int fd, const void *buffer, size_t cnt)
104
{
105
    _ssize_t      ret;
106
    unsigned int  iomode_flags;
107
    unsigned      len_written, i, j;
108
    int           rc2;
109
    char         *buf;
110
 
111
    __io_handle  *ioh;
112
 
113
    if( (fd < 0) || (fd >=64) )
114
    {
115
        errno = EBADF;
116
        return -1;
117
    };
118
 
119
    ioh = &__io_tab[fd];
120
 
121
    iomode_flags = ioh->mode;
122
 
123
    if( iomode_flags == 0 )
124
    {
125
        errno = EBADF;
126
        return( -1 );
127
    }
128
 
129
    if( !(iomode_flags & _WRITE) )
130
    {
131
        errno = EACCES ;
132
        return( -1 );
133
    }
134
 
135
    if( (iomode_flags & _APPEND) && !(iomode_flags & _ISTTY) )
136
    {
137
        ioh->offset = lseek(fd, 0L, SEEK_END );   /* end of data offset */
138
    }
139
 
140
    len_written = 0;
141
    rc2 = 0;
142
 
143
    // Pad the file with zeros if necessary
144
    if( iomode_flags & _FILEEXT )
145
    {
146
        // turn off file extended flag
147
        ioh->mode = iomode_flags & (~_FILEEXT);
148
 
149
        // It is not required to pad a file with zeroes on an NTFS file system;
150
        // unfortunately it is required on FAT (and probably FAT32). (JBS)
151
//        rc2 = zero_pad( ptr, fd );
152
    }
153
 
154
    if( rc2 == 0 )
155
    {
156
        if( iomode_flags & _BINARY ) {  /* if binary mode */
157
            rc2 = os_write(fd, buffer, cnt, &len_written );
158
            /* end of binary mode part */
159
        } else {    /* text mode */
160
 
161
            int buf_size = 512;
162
 
163
            buf = (char*)alloca( buf_size );
164
 
165
            j = 0;
166
            for( i = 0; i < cnt; )
167
            {
168
                if( ((const char*)buffer)[i] == '\n' )
169
                {
170
                    buf[j] = '\r';
171
                    ++j;
172
                    if( j == buf_size )
173
                    {
174
                        rc2 = os_write(fd, buf, buf_size, &j );
175
                        if( rc2 == -1 )
176
                            break;
177
                        len_written += j;
178
                        if( rc2 == ENOSPC )
179
                            break;
180
                        len_written = i;
181
                        j = 0;
182
                    }
183
                }
184
                buf[j] = ((const char*)buffer)[i];
185
                ++i;
186
                ++j;
187
                if( j == buf_size ) {
188
                    rc2 = os_write(fd, buf, buf_size, &j );
189
                    if( rc2 == -1 )
190
                        break;
191
                    len_written += j;
192
                    if( rc2 == ENOSPC )
193
                        break;
194
                    len_written = i;
195
                    j = 0;
196
                }
197
            }
198
            if( j ) {
199
                rc2 = os_write(fd, buf, j, &i );
200
                if( rc2 == ENOSPC ) {
201
                    len_written += i;
202
                } else {
203
                    len_written = cnt;
204
                }
205
            }
206
            /* end of text mode part */
207
        }
208
    }
209
 
210
    if( rc2 == -1 ) {
211
        return( rc2 );
212
    } else {
213
        return( len_written );
214
    }
215
 
216
  return 0;
217
}
218