unstack - fix ipcvecs
[minix.git] / sys / arch / i386 / stand / lib / dosfile.c
blobe2ab313e48cea6988905ecea28a90f12f431ee31
1 /* $NetBSD: dosfile.c,v 1.15 2011/06/16 13:27:59 joerg Exp $ */
3 /*
4 * Copyright (c) 1996
5 * Matthias Drochner. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 * DOS filesystem for libsa
31 * standalone - uses no device, works only with DOS running
32 * needs lowlevel parts from dos_file.S
35 #include <lib/libsa/stand.h>
37 #include "diskbuf.h"
38 #include "dosfile.h"
40 extern int dosopen(const char *);
41 extern void dosclose(int);
42 extern int dosread(int, char *, int);
43 extern int dosseek(int, int, int);
45 struct dosfile {
46 int doshandle, off;
49 extern int doserrno; /* in dos_file.S */
51 static int dos2errno(void);
53 static int
54 dos2errno(void)
56 int err;
58 switch (doserrno) {
59 case 1:
60 case 4:
61 case 12:
62 default:
63 err = EIO;
64 case 2:
65 case 3:
66 err = ENOENT;
67 case 5:
68 err = EPERM;
69 case 6:
70 err = EINVAL;
72 return err;
75 __compactcall int
76 dos_open(const char *path, struct open_file *f)
78 struct dosfile *df;
80 df = (struct dosfile *) alloc(sizeof(*df));
81 if (!df)
82 return -1;
84 df->off = 0;
85 df->doshandle = dosopen(path);
86 if (df->doshandle < 0) {
87 #ifdef DEBUG
88 printf("DOS error %d\n", doserrno);
89 #endif
90 dealloc(df, sizeof(*df));
91 return dos2errno();
93 f->f_fsdata = (void *) df;
94 return 0;
97 __compactcall int
98 dos_read(struct open_file *f, void *addr, size_t size, size_t *resid)
100 struct dosfile *df;
101 int got;
102 static int tc = 0;
104 df = (struct dosfile *) f->f_fsdata;
106 if (!(tc++ % 4))
107 twiddle();
109 if ((unsigned long) addr >= 0x10000) {
110 u_int lsize = size;
112 while (lsize > 0) {
113 u_int tsize;
114 size_t tgot;
115 char *p = addr;
117 tsize = lsize;
119 if (tsize > DISKBUFSIZE)
120 tsize = DISKBUFSIZE;
122 alloc_diskbuf(dos_read);
124 tgot = dosread(df->doshandle, diskbufp, tsize);
125 if (tgot < 0) {
126 #ifdef DEBUG
127 printf("DOS error %d\n", doserrno);
128 #endif
129 return dos2errno();
131 memcpy(p, diskbufp, tgot);
133 p += tgot;
134 lsize -= tgot;
136 if (tgot != tsize)
137 break; /* EOF */
139 got = size - lsize;
140 } else {
141 got = dosread(df->doshandle, addr, size);
143 if (got < 0) {
144 #ifdef DEBUG
145 printf("DOS error %d\n", doserrno);
146 #endif
147 return dos2errno();
151 df->off += got;
152 size -= got;
154 if (resid)
155 *resid = size;
156 return 0;
159 __compactcall int
160 dos_close(struct open_file *f)
162 struct dosfile *df;
163 df = (struct dosfile *) f->f_fsdata;
165 dosclose(df->doshandle);
167 if (df)
168 dealloc(df, sizeof(*df));
169 return 0;
172 __compactcall int
173 dos_write(struct open_file *f, void *start, size_t size, size_t *resid)
175 return EROFS;
178 __compactcall int
179 dos_stat(struct open_file *f, struct stat *sb)
181 struct dosfile *df;
182 df = (struct dosfile *) f->f_fsdata;
184 sb->st_mode = 0444;
185 sb->st_nlink = 1;
186 sb->st_uid = 0;
187 sb->st_gid = 0;
188 sb->st_size = -1;
189 return 0;
192 __compactcall off_t
193 dos_seek(struct open_file *f, off_t offset, int where)
195 struct dosfile *df;
196 int doswhence, res;
197 #ifdef DOS_CHECK
198 int checkoffs;
199 #endif
200 df = (struct dosfile *) f->f_fsdata;
202 switch (where) {
203 case SEEK_SET:
204 doswhence = 0;
205 #ifdef DOS_CHECK
206 checkoffs = offset; /* don't trust DOS */
207 #endif
208 break;
209 case SEEK_CUR:
210 doswhence = 1;
211 #ifdef DOS_CHECK
212 checkoffs = df->off + offset;
213 #endif
214 break;
215 case SEEK_END:
216 doswhence = 2;
217 #ifdef DOS_CHECK
218 checkoffs = -1; /* we dont know len */
219 #endif
220 break;
221 default:
222 errno = EOFFSET;
223 return -1;
225 res = dosseek(df->doshandle, offset, doswhence);
226 if (res == -1) {
227 errno = dos2errno();
228 return -1;
230 #ifdef DOS_CHECK
231 if ((checkoffs != -1) && (res != checkoffs)) {
232 printf("dosfile: unexpected seek result (%d+%d(%d)=%d)\n",
233 df->off, offset, where, res);
234 errno = EOFFSET;
235 return -1;
237 #endif
238 df->off = res;
239 return res;