* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / libc / bios / fileops.c
blob9c2daf5dd7fc219b97e9ec0c183c3d9aeb19c1a3
2 #include <bios.h>
3 #include <fcntl.h>
4 #include <errno.h>
6 #include "io.h"
7 #include "rawio.h"
9 static int op_open();
10 static int op_close();
11 static int op_read();
12 static int op_write();
13 static long op_lseek();
14 static int fileops();
16 int
17 open(name, flags, mode)
18 char * name;
19 int flags, mode;
21 __files = fileops;
22 return (*__files)(CMD_OPEN, flags, name, mode);
25 static int
26 fileops(cmd, fd, buf, len)
27 int cmd, fd, len;
28 char * buf;
30 switch(cmd)
32 case CMD_OPEN: return op_open(buf, fd, len);
33 case CMD_READ: return op_read(fd, buf, len);
35 case CMD_WRITE: return op_write(fd, buf, len);
36 case CMD_LSEEK: rv = op_lseek(fd, *(long*)buf, len);
37 (*(long*)buf) = rv;
38 if( rv == -1 ) return -1;
39 else return 0;
41 case CMD_CLOSE: return op_close(fd);
44 errno=EINVAL;
45 return -1;
48 #define MAX_OPEN_FILES 5
49 ioblock _iob[MAX_OPEN_FILES];
51 static int
52 op_read(fd,buf,len)
53 int fd,len;
54 char * buf;
56 ioblock* cur = &_iob[fd];
57 int amount_read = 0;
58 int amount_left_in_buffer;
59 int amount_to_copy;
61 if (fd < 0 || fd >= MAX_OPEN_FILES || _iob[fd].block_read == 0)
63 errno = EBADF;
64 return -1;
67 while (len > 0)
69 /* pull in next block as required */
70 if (cur->amount_left <= 0)
72 int read_len = cur->block_read(cur,
73 cur->buffer,
74 (long) cur->offset / sizeof(cur->buffer)
76 #ifdef DEBUG
77 fprintf(stderr, "br: returned %d\n", read_len);
78 #endif
79 if (read_len <= 0)
80 break;
81 cur->amount_left = read_len;
83 if (cur->amount_left > len)
84 amount_to_copy = len;
85 else
86 amount_to_copy = cur->amount_left;
88 #ifdef DEBUG
89 fprintf(stderr, "r: len=%d, amount_left=%ld, offset=%ld, buf=%x\n",
90 len, cur->amount_left, cur->offset,
91 (int) cur->buffer[cur->offset % sizeof(cur->buffer)]);
92 #endif
93 memcpy(buf,
94 &cur->buffer[cur->offset % sizeof(cur->buffer)],
95 amount_to_copy);
96 amount_read += amount_to_copy;
97 len -= amount_to_copy;
98 cur->offset += amount_to_copy;
99 buf += amount_to_copy;
100 cur->amount_left -= amount_to_copy;
102 return amount_read;
105 /****************************************************************************/
107 static int
108 op_open(name, flags, mode)
109 char * name;
110 int flags, mode;
112 int fd;
113 ioblock* cur;
116 * discover whether the iob has been initialised or not
118 if (_iob[0].flags == 0)
120 _iob[0].flags = O_RDONLY;
121 _iob[1].flags = O_WRONLY;
122 _iob[2].flags = O_WRONLY;
125 * discover next free iob
127 for (fd = 3; fd < MAX_OPEN_FILES; ++fd)
129 if (_iob[fd].block_read == NULL && _iob[fd].block_write == NULL)
130 break;
132 if (fd >= MAX_OPEN_FILES)
134 errno = EMFILE; /* too many open files */
135 return -1;
139 * try and find the file
141 cur = &_iob[fd];
142 if (fsdos_open_file(cur, name, flags, mode) >= 0)
144 cur->amount_left = 0;
145 cur->offset = 0;
146 return fd;
148 cur->block_read = NULL; /* ensure that the file is closed */
149 cur->block_write = NULL;
150 errno = ENOENT;
151 return -1;
154 /****************************************************************************/
156 static int
157 op_close(fd)
158 int fd;
160 if (fd < 0 || fd >= MAX_OPEN_FILES || _iob[0].flags == 0)
162 errno = EBADF;
163 return -1;
165 else
167 ioblock* cur = &_iob[fd];
168 cur->close(cur);
169 cur->block_read = NULL;
170 cur->block_write = NULL;
171 cur->close = NULL;
172 cur->flags = 0;
173 return 0;
177 /****************************************************************************/