Subversion Repositories Kolibri OS

Rev

Rev 4874 | Rev 6330 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4874 Rev 4921
Line -... Line 1...
-
 
1
/* write.c -- write bytes to an output device.
-
 
2
 *
-
 
3
 * Copyright (c) 1995 Cygnus Support
1
#include 
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 
2
#include 
17
#include 
-
 
18
#include 
-
 
19
#include 
3
 
20
#include 
-
 
21
#include "glue.h"
-
 
22
#include "io.h"
-
 
23
 
-
 
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
/*******************************/
-
 
33
{
-
 
34
    int         rc;
-
 
35
    long        curPos, eodPos;
-
 
36
    long        bytesToWrite;
-
 
37
    unsigned    writeAmt;
-
 
38
    char        zeroBuf[PAD_SIZE];
Line 4... Line 39...
4
int write_file(const char *path,const void *buff,
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;
5
               size_t offset, size_t count, size_t *writes)
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
 
6
{
75
static int os_write(int handle, const void *buffer, unsigned len, unsigned *amt )
7
     int retval;
76
{
8
     __asm__ __volatile__(
77
    __io_handle *ioh;
-
 
78
    int          rc;
9
     "pushl $0 \n\t"
79
 
10
     "pushl $0 \n\t"
80
    rc   = 0;
-
 
81
    *amt = 0;
11
     "movl %%eax, 1(%%esp) \n\t"
82
 
-
 
83
    ioh = &__io_tab[handle];
-
 
84
 
-
 
85
    rc = ioh->write(ioh->name,(const void*)buffer,ioh->offset,len,amt);
12
     "pushl %%ebx \n\t"
86
 
-
 
87
    ioh->offset+= *amt;
13
     "pushl %%edx \n\t"
88
 
14
     "pushl $0 \n\t"
89
    if( *amt != len )
15
     "pushl %%ecx \n\t"
90
    {
-
 
91
        rc = ENOSPC;
-
 
92
    }
16
     "pushl $3 \n\t"
93
 
-
 
94
    return( rc );
-
 
95
}
-
 
96
 
-
 
97
/*
-
 
98
 * write -- write bytes to the serial port. Ignore fd, since
17
     "movl %%esp, %%ebx \n\t"
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)
18
     "mov $70, %%eax \n\t"
103
{
19
     "int $0x40 \n\t"
104
    _ssize_t      ret;
20
     "testl %%esi, %%esi \n\t"
105
    unsigned int  iomode_flags;
21
     "jz 1f \n\t"
106
    unsigned      len_written, i, j;
22
     "movl %%ebx, (%%esi) \n\t"
107
    int           rc2;
23
"1:"
108
    char         *buf;
24
     "addl $28, %%esp \n\t"
109
 
-
 
110
    __io_handle  *ioh;
25
     :"=a" (retval)
111
 
-
 
112
    if( (fd < 0) || (fd >=64) )
26
     :"a"(path),"b"(buff),"c"(offset),"d"(count),"S"(writes));
113
    {
27
    return retval;
114
        errno = EBADF;
28
};
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
}