Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4973 | right-hear | 1 | #include "dosemuin.h" |
2 | #include |
||
3 | |||
4 | static char _io_filename[256]; |
||
5 | |||
6 | static inline int sys_systree(struct systree_info * i,int * EBX) |
||
7 | { |
||
8 | int d0,d1; |
||
9 | __asm__ __volatile__("int $0x40" |
||
10 | :"=a"(d0),"=b"(d1) |
||
11 | :"0"(70),"1"((unsigned long)i) |
||
12 | :"memory"); |
||
13 | if(EBX) *EBX=d1; |
||
14 | return d0; |
||
15 | } |
||
16 | |||
17 | int dosemu_file_exists(const char * filename) |
||
18 | { |
||
19 | struct systree_info finf; |
||
20 | struct bdfe_item attr; |
||
21 | finf.command = 5; |
||
22 | finf.file_offset_low = 0; |
||
23 | finf.file_offset_high = 0; |
||
24 | finf.size = 0; |
||
25 | finf.data_pointer = (__u32)&attr; |
||
26 | finf._zero = 0; |
||
27 | finf.nameptr = filename; |
||
28 | if (sys_systree(&finf,NULL)!=0) |
||
29 | return -1; |
||
30 | return (int)attr.filesize_low; |
||
31 | } |
||
32 | |||
33 | int dosemu_createtrunc(const char * filename) |
||
34 | { |
||
35 | struct systree_info finf; |
||
36 | finf.command = 2; |
||
37 | finf.file_offset_low = finf.file_offset_high = 0; |
||
38 | finf.size = 0; |
||
39 | finf.data_pointer = 0; |
||
40 | finf._zero = 0; |
||
41 | finf.nameptr = filename; |
||
42 | if (sys_systree(&finf,NULL)) |
||
43 | return -1; |
||
44 | return 0; |
||
45 | } |
||
46 | |||
47 | _io_struct * dosemu_getiostruct(int handle) |
||
48 | { |
||
49 | if(handle<0 || handle>=_MAX_HANDLES) return NULL; |
||
50 | if(_io_handles[handle].oflags==-1) return NULL; |
||
51 | return _io_handles+handle; |
||
52 | } |
||
53 | |||
54 | int dosemu_allochandle(void) |
||
55 | { |
||
56 | int i; |
||
57 | for(i=0;i<_MAX_HANDLES;i++) |
||
58 | if(_io_handles[i].oflags==-1) return i; |
||
59 | return -1; |
||
60 | } |
||
61 | |||
62 | int dosemu_freehandle(int i) |
||
63 | { |
||
64 | if(i<0) return; |
||
65 | _io_handles[i].oflags=-1; |
||
66 | } |
||
67 | |||
68 | int dosemu_fileread(_io_struct * sh,char * buffer,int count) |
||
69 | { |
||
70 | struct systree_info finf; |
||
71 | int res,ebx; |
||
72 | finf.command = 0; |
||
73 | finf.file_offset_low = sh->pointer; |
||
74 | finf.file_offset_high = 0; |
||
75 | finf.size = count; |
||
76 | finf.data_pointer = (__u32)buffer; |
||
77 | finf._zero = 0; |
||
78 | finf.nameptr = sh->filename; |
||
79 | res = sys_systree(&finf,&ebx); |
||
80 | if (res != 0 && res != 6) |
||
81 | return -1; |
||
82 | sh->pointer += ebx; |
||
83 | return ebx; |
||
84 | } |
||
85 | |||
86 | int dosemu_filewrite(_io_struct * sh,char * buffer,int count) |
||
87 | { |
||
88 | struct systree_info finf; |
||
89 | int res,ebx; |
||
90 | finf.command = 3; |
||
91 | finf.file_offset_low = sh->pointer; |
||
92 | finf.file_offset_high = 0; |
||
93 | finf.size = count; |
||
94 | finf.data_pointer = (__u32)buffer; |
||
95 | finf._zero = 0; |
||
96 | finf.nameptr = sh->filename; |
||
97 | res = sys_systree(&finf,&ebx); |
||
98 | if (res != 0 && res != 6) |
||
99 | return -1; |
||
100 | sh->pointer += ebx; |
||
101 | if (sh->size < sh->pointer) |
||
102 | sh->size = sh->pointer; |
||
103 | return ebx; |
||
104 | } |
||
105 | |||
106 | int dosemu_iosize(int handle) |
||
107 | { |
||
108 | _io_struct * sh=dosemu_getiostruct(handle); |
||
109 | if(!sh) return -1; |
||
110 | return sh->size; |
||
111 | } |
||
112 | |||
113 | int dosemu_filesize(char * filename) |
||
114 | { |
||
115 | return dosemu_file_exists(filename); |
||
116 | } |
||
117 | |||
118 | static char fn_buf[256]; |
||
119 | |||
120 | int dosemu_open(char * filename,int oflags) |
||
121 | { |
||
122 | int baseflags,h,fsize; |
||
123 | _fixpath(filename,_io_filename); |
||
124 | baseflags=oflags&(O_RDONLY|O_WRONLY|O_RDWR); |
||
125 | h=dosemu_allochandle(); |
||
126 | fsize=dosemu_file_exists(_io_filename); |
||
127 | if(oflags & O_CREAT) |
||
128 | { |
||
129 | int creatflags=oflags & (O_EXCL|O_TRUNC); |
||
130 | if(creatflags & O_EXCL) |
||
131 | { |
||
132 | if(fsize>=0) |
||
133 | { |
||
134 | dosemu_freehandle(h); |
||
135 | return -1; |
||
136 | } |
||
137 | } |
||
138 | if(fsize<0 || (creatflags&O_TRUNC)) |
||
139 | { |
||
140 | if(dosemu_createtrunc(_io_filename)<0) |
||
141 | { |
||
142 | dosemu_freehandle(h); |
||
143 | return -1; |
||
144 | } |
||
145 | fsize=0; |
||
146 | } |
||
147 | } |
||
148 | else if (fsize<0) |
||
149 | { |
||
150 | dosemu_freehandle(h); |
||
151 | return -1; |
||
152 | } |
||
153 | _io_handles[h].oflags=oflags; |
||
154 | _io_handles[h].size=fsize; |
||
155 | _io_handles[h].pointer=0; |
||
156 | switch (baseflags) |
||
157 | { |
||
158 | case O_RDONLY:_io_handles[h].flags=_IO_READ;break; |
||
159 | case O_WRONLY:_io_handles[h].flags=_IO_WRITE;break; |
||
160 | case O_RDWR:_io_handles[h].flags=_IO_READ|_IO_WRITE;break; |
||
161 | default:dosemu_freehandle(h);return -1; |
||
162 | } |
||
163 | strcpy(_io_handles[h].filename,_io_filename); |
||
164 | return h; |
||
165 | } |
||
166 | |||
167 | int dosemu_tell(int handle) |
||
168 | { |
||
169 | _io_struct * sh=dosemu_getiostruct(handle); |
||
170 | if(!sh) return -1; |
||
171 | return sh->pointer; |
||
172 | } |
||
173 | |||
174 | int dosemu_lseek(int handle,long offset,int origin) |
||
175 | { |
||
176 | int newpointer=0; |
||
177 | _io_struct *sh=dosemu_getiostruct(handle); |
||
178 | if(!sh)return -1; |
||
179 | if(handle==0 || handle==1 || handle==2 || handle==3) return -1; |
||
180 | switch(origin) |
||
181 | { |
||
182 | case SEEK_SET: newpointer=offset;break; |
||
183 | case SEEK_CUR: newpointer=sh->pointer+offset;break; |
||
184 | case SEEK_END: newpointer=sh->size+offset;break; |
||
185 | } |
||
186 | if(newpointer<0)return -1; |
||
187 | sh->pointer=newpointer; |
||
188 | return newpointer; |
||
189 | } |
||
190 | |||
191 | int dosemu_read( int handle, void *buffer, unsigned int count ) |
||
192 | { |
||
193 | _io_struct *sh=dosemu_getiostruct(handle); |
||
194 | if(!sh)return -1; |
||
195 | if(!(sh->flags&_IO_READ)) return -1; |
||
196 | return dosemu_fileread(sh,buffer,count); |
||
197 | } |
||
198 | |||
199 | int dosemu_write( int handle, void *buffer, unsigned int count ) |
||
200 | { |
||
201 | _io_struct *sh=dosemu_getiostruct(handle); |
||
202 | int k; |
||
203 | if(!sh)return -1; |
||
204 | if(!(sh->flags&_IO_WRITE)) return -1; |
||
205 | return dosemu_filewrite(sh,buffer,count); |
||
206 | } |
||
207 | |||
208 | int dosemu_close( int handle ) |
||
209 | { |
||
210 | _io_struct *sh=dosemu_getiostruct(handle); |
||
211 | if(!sh)return -1; |
||
212 | dosemu_freehandle(handle); |
||
213 | return 0; |
||
214 | } |
||
215 | |||
216 | void _dosemu_flush(int handle) |
||
217 | {} |
||
218 | |||
219 | int dosemu_truncate(int fd, off_t where) |
||
220 | { |
||
221 | struct systree_info finf; |
||
222 | int res; |
||
223 | _io_struct* sh = dosemu_getiostruct(fd); |
||
224 | if (!sh) return EBADF; |
||
225 | if (!(sh->flags & _IO_WRITE)) return EBADF; |
||
226 | finf.command = 4; |
||
227 | finf.file_offset_low = where; |
||
228 | finf.file_offset_high = 0; |
||
229 | finf.size = 0; |
||
230 | finf.data_pointer = 0; |
||
231 | finf._zero = 0; |
||
232 | finf.nameptr = sh->filename; |
||
233 | res = sys_systree(&finf,NULL); |
||
234 | if (res == 8) return ENOSPC; |
||
235 | if (res) return EACCES; |
||
236 | sh->size = where; |
||
237 | return 0; |
||
238 | }0)return>0) |