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 | }>>> |