source: vendor/emx/current/src/dos/fileio.asm

Last change on this file was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 31.2 KB
Line 
1;
2; FILEIO.ASM -- Handle files and file handles
3;
4; Copyright (c) 1991-1996 by Eberhard Mattes
5;
6; This file is part of emx.
7;
8; emx is free software; you can redistribute it and/or modify it
9; under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 2, or (at your option)
11; any later version.
12;
13; emx is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17;
18; You should have received a copy of the GNU General Public License
19; along with emx; see the file COPYING. If not, write to
20; the Free Software Foundation, 59 Temple Place - Suite 330,
21; Boston, MA 02111-1307, USA.
22;
23; See emx.asm for a special exception.
24;
25
26 INCLUDE EMX.INC
27 INCLUDE SIGNAL.INC
28 INCLUDE PROCESS.INC
29 INCLUDE SWAPPER.INC
30 INCLUDE ERRORS.INC
31 INCLUDE OPTIONS.INC
32 INCLUDE OPRINT.INC
33 INCLUDE PMINT.INC
34 INCLUDE UTILS.INC
35
36TOTAL_FILES = 128
37
38SV_DATA SEGMENT
39
40;
41; For each DOS file handle, this array contains the number of times
42; the handle is referenced.
43;
44DOS_REF_COUNT DW TOTAL_FILES DUP (?)
45
46$CHECK_HANDLES DB "Internal error: wrong handle reference count", 0
47
48$DIR_DEV BYTE "DEV", 0
49$DIR_PIPE BYTE "PIPE", 0
50
51SV_DATA ENDS
52
53
54SV_CODE SEGMENT
55
56 ASSUME CS:SV_CODE, DS:NOTHING
57
58;
59; Implementation of __dup()
60;
61; In: AX File handle
62; BX Pointer to process table entry
63;
64; Out: AX errno if CY set
65; AX File handle if CY clear
66; CY Error
67;
68; Find an available file handle, then use common code for
69; DO_DUP and DO_DUP2.
70;
71 TALIGN 4
72 ASSUME DS:SV_DATA
73 ASSUME BX:PTR PROCESS
74DO_DUP PROC NEAR
75;
76; Check the file handle
77;
78 CMP AX, MAX_FILES
79 JAE SHORT DUP_EBADF
80 MOV SI, AX
81 SHL SI, 1
82 CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE
83 JE SHORT DUP_EBADF
84;
85; Find an available file handle
86;
87 MOV SI, 0
88 MOV CX, 0
89DUP_LOOP: CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE
90 JE DUP_FOUND
91 ADD SI, 2
92 INC CX
93 CMP CX, MAX_FILES
94 JB SHORT DUP_LOOP
95 MOV AX, EMFILE ; Too many open files
96 STC
97 RET
98
99DUP_EBADF: MOV AX, EBADF
100 STC
101 RET
102
103;
104; File handle found, call common code
105;
106DUP_FOUND: CALL DUP_COMMON
107 CLC
108 RET
109 ASSUME BX:NOTHING
110DO_DUP ENDP
111
112
113;
114; Implementation of __dup2()
115;
116; In: AX Source handle
117; CX Target handle
118; BX Pointer to process table entry
119;
120; Out: AX errno if CY set
121; AX File handle if CY clear
122;
123; Check the file handles, then use common code for
124; DO_DUP and DO_DUP2.
125;
126 TALIGN 4
127 ASSUME DS:SV_DATA
128 ASSUME BX:PTR PROCESS
129DO_DUP2 PROC NEAR
130;
131; Check the source file handle
132;
133 CMP AX, MAX_FILES
134 JAE SHORT DUP2_EBADF
135 MOV SI, AX
136 SHL SI, 1
137 CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE
138 JE SHORT DUP2_EBADF
139;
140; Do nothing if the two handles are identical
141;
142 CMP AX, CX ; Handles identical?
143 JE SHORT DUP2_OK ; Yes -> return the handle
144;
145; Check the target file handle. Close the target handle if it is open
146;
147 CMP CX, MAX_FILES
148 JAE SHORT DUP2_EBADF
149 MOV SI, CX
150 SHL SI, 1
151 CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE
152 JE SHORT DUP2_CONT
153 PUSH AX
154 PUSH CX
155 MOV AX, CX
156 CALL DO_CLOSE
157 POP CX
158 POP DX
159 JC SHORT DUP2_RET ; Error
160 MOV AX, DX
161;
162; Call common code
163;
164DUP2_CONT: CALL DUP_COMMON
165DUP2_OK: CLC
166DUP2_RET: RET
167
168DUP2_EBADF: MOV AX, EBADF
169 STC
170 RET
171
172 ASSUME BX:NOTHING
173DO_DUP2 ENDP
174
175
176;
177; Common code for DO_DUP and DO_DUP2, both handles have been checked,
178; no error is possible. The target handle is available.
179;
180; In: AX Source handle
181; CX Target handle
182; BX Pointer to process table entry
183;
184; Out: AX File handle
185;
186 TALIGN 4
187 ASSUME DS:SV_DATA
188 ASSUME BX:PTR PROCESS
189DUP_COMMON PROC NEAR
190 MOV SI, AX
191 SHL SI, 1
192 MOV AX, [BX].P_HFLAGS[SI]
193 MOV DX, [BX].P_HANDLES[SI]
194 MOV SI, CX
195 SHL SI, 1
196 MOV [BX].P_HANDLES[SI], DX
197 AND AX, NOT HF_NOINHERIT ; Clear FD_CLOEXEC
198 MOV [BX].P_HFLAGS[SI], AX
199 MOV SI, DX
200 SHL SI, 1
201 INC DOS_REF_COUNT[SI]
202 MOV AX, CX
203 CALL MAYBE_CHECK_HANDLES
204 RET
205 ASSUME BX:NOTHING
206DUP_COMMON ENDP
207
208;
209; Close a file handle
210;
211; In: AX File handle
212; BX Pointer to process table entry
213;
214; Out: AX errno if CY set
215; CY Error
216;
217 TALIGN 4
218 ASSUME DS:SV_DATA
219 ASSUME BX:PTR PROCESS
220DO_CLOSE PROC NEAR
221 PUSH DX
222 PUSH SI
223 CMP AX, MAX_FILES
224 JAE SHORT CLOSE_EBADF
225 MOV SI, AX
226 SHL SI, 1
227 MOV DX, [BX].P_HANDLES[SI]
228 CMP DX, NO_FILE_HANDLE
229 JE SHORT CLOSE_EBADF
230 MOV [BX].P_HANDLES[SI], NO_FILE_HANDLE
231 MOV [BX].P_HFLAGS[SI], 0
232 MOV SI, DX
233 SHL SI, 1
234;
235; The reference count should not be zero here. Handle that case, anyway.
236;
237 CMP DOS_REF_COUNT[SI], 0
238 JE SHORT CLOSE_CLOSE
239 DEC DOS_REF_COUNT[SI]
240 JNZ SHORT CLOSE_OK
241;
242; Close the DOS file handle
243;
244CLOSE_CLOSE: PUSH BX
245 MOV BX, DX
246 MOV AH, 3EH
247 PUSH PROCESS_PTR
248 MOV PROCESS_PTR, NO_PROCESS
249 INT 21H
250 POP PROCESS_PTR
251 POP BX
252 JMP SHORT CLOSE_RET
253
254CLOSE_OK: CALL MAYBE_CHECK_HANDLES
255 XOR AX, AX
256CLOSE_RET: POP SI
257 POP DX
258 RET
259
260CLOSE_EBADF: MOV AX, EBADF
261 STC
262 JMP SHORT CLOSE_RET
263 ASSUME BX:NOTHING
264DO_CLOSE ENDP
265
266
267;
268; Translate file handle (process PROCESS_PTR) to DOS file handle
269;
270; In: AX File handle
271; PROCESS_PTR
272;
273; Out: AX DOS file handle (NO_FILE_HANDLE if file not open)
274; CY Not a valid handle
275;
276 TALIGN 4
277 ASSUME DS:SV_DATA
278GET_HANDLE PROC NEAR
279 CMP AX, MAX_FILES
280 JAE SHORT GET_HANDLE_ERR
281 PUSH BX
282 PUSH SI
283 MOV SI, AX
284 SHL SI, 1
285 MOV BX, PROCESS_PTR
286 MOV AX, (PROCESS PTR [BX]).P_HANDLES[SI]
287 POP SI
288 POP BX
289 CLC
290 RET
291GET_HANDLE_ERR: MOV AX, NO_FILE_HANDLE
292 STC
293 RET
294GET_HANDLE ENDP
295
296
297;
298; Put new handle into handle translation table
299;
300; In: AX DOS file handle
301; PROCESS_PTR
302;
303; Out: CY No empty slot found
304; EAX emx file handle
305;
306; Note:
307; When called with AX=NO_FILE_HANDLE, this function just looks for an
308; empty slot, but does not use that slot.
309;
310
311 TALIGN 4
312 ASSUME DS:SV_DATA
313NEW_HANDLE PROC NEAR
314 PUSH BX
315 PUSH DX
316 PUSH SI
317 MOV BX, PROCESS_PTR
318 MOV SI, 0
319 MOV DX, 0
320 ASSUME BX:PTR PROCESS
321 TALIGN 4
322NH_LOOP: CMP [BX].P_HANDLES[SI], NO_FILE_HANDLE ; Empty slot?
323 JE SHORT NH_FOUND ; Yes -> use it
324 ADD SI, 2 ; Next slot
325 INC DX
326 CMP DX, MAX_FILES
327 JB SHORT NH_LOOP
328NH_ERROR: STC ; Out of file handles
329 JMP SHORT NH_RET
330
331 TALIGN 4
332NH_FOUND: CMP AX, NO_FILE_HANDLE
333 JE SHORT NH_OK
334 CMP AX, TOTAL_FILES
335 JAE SHORT NH_ERROR
336 MOV [BX].P_HANDLES[SI], AX ; Store DOS file handle
337 MOV [BX].P_HFLAGS[SI], 0 ; Clear handle flags
338 MOV SI, AX
339 SHL SI, 1
340 MOV DOS_REF_COUNT[SI], 1
341NH_OK: MOVZX EAX, DX
342 CALL MAYBE_CHECK_HANDLES
343 CLC
344NH_RET: POP SI
345 POP DX
346 POP BX
347 RET
348 ASSUME BX:NOTHING
349NEW_HANDLE ENDP
350
351;
352; Remap file handles to make the DOS handle identical to the user process'
353; handle.
354;
355; In: AX File handle
356; PROCESS_PTR
357;
358; Out: AX errno if CY is set
359; CY Error
360;
361; TODO: Handle HF_NOINHERIT.
362;
363MH_HANDLE EQU (WORD PTR [BP-1*2])
364MH_RELOC EQU (WORD PTR [BP-2*2])
365MH_DOSHANDLE EQu (WORD PTR [BP-3*2])
366
367 TALIGN 4
368 ASSUME DS:SV_DATA
369MAP_HANDLE PROC NEAR
370 PUSH BX
371 PUSH CX
372 PUSH DX
373 PUSH SI
374 PUSH BP
375 MOV BP, SP
376 SUB SP, 3 * 2
377 MOV MH_HANDLE, AX
378 MOV BX, PROCESS_PTR
379 ASSUME BX:PTR PROCESS
380 MOV SI, AX
381 SHL SI, 1
382 MOV DX, [BX].P_HANDLES[SI] ; Fetch curent DOS handle
383 CMP AX, DX ; Mapping required?
384 JE MH_OK ; No -> done
385 MOV MH_DOSHANDLE, DX
386;
387; Check whether we have to relocate the DOS handle. It must be relocated
388; if it is used.
389;
390 CMP DOS_REF_COUNT[SI], 0 ; DOS handle used at all?
391 JNE SHORT MH_RELOCATE ; Yes -> relocate
392 CMP AX, SWAP_HANDLE ; Used for swap file?
393 JE SHORT MH_RELOCATE ; Yes -> relocate
394;
395; Check whether the handle is used for an executable file
396;
397 LEA BX, PROCESS_TABLE
398 MOV CX, MAX_PROCESSES
399MH_EXEC_LOOP: CMP AX, [BX].P_EXEC_HANDLE
400 JE SHORT MH_RELOCATE
401 ADD BX, SIZE PROCESS
402 LOOP MH_EXEC_LOOP
403 JMP SHORT MH_NO_RELOC
404;
405; Relocate the DOS handle to make it available, updating the translation
406; tables of all processes
407;
408MH_RELOCATE: MOV BX, MH_HANDLE
409 ASSUME BX:NOTHING
410 MOV AH, 45H
411 PUSH PROCESS_PTR
412 MOV PROCESS_PTR, NO_PROCESS
413 INT 21H
414 POP PROCESS_PTR
415 JC MH_RET
416 CMP AX, TOTAL_FILES
417 JAE MH_ERROR
418 MOV MH_RELOC, AX ; Relocated handle
419
420 MOV AH, 3EH ; Close the original handle
421 PUSH PROCESS_PTR
422 MOV PROCESS_PTR, NO_PROCESS
423 INT 21H
424 POP PROCESS_PTR
425 MOV AX, MH_HANDLE
426 MOV DX, MH_RELOC
427 CALL MAP_TRANSLATE
428;
429; Move the DOS handle previously associated with MH_HANDLE to DOS handle
430; MH_HANDLE.
431;
432MH_NO_RELOC: MOV BX, MH_DOSHANDLE ; Is the handle associated
433 CMP BX, NO_FILE_HANDLE ; with a DOS handle?
434 JE SHORT MH_OK ; No -> done (it's closed now)
435 CMP BX, MH_HANDLE ; Same handle?
436 JE SHORT MH_OK ; Yes -> done
437 MOV CX, MH_HANDLE
438 MOV AH, 46H
439 PUSH PROCESS_PTR
440 MOV PROCESS_PTR, NO_PROCESS
441 INT 21H
442 POP PROCESS_PTR
443 JC SHORT MH_RET
444;
445; Update the P_HANDLES entry for this one handle, leaving the other entries
446; of this process and other processes point to the duplicate made above.
447; If there are no other entries, we can close the handle.
448;
449 MOV BX, PROCESS_PTR
450 ASSUME BX:PTR PROCESS
451 MOV AX, MH_HANDLE
452 MOV SI, AX
453 SHL SI, 1
454 MOV [BX].P_HANDLES[SI], AX
455 ASSUME BX:NOTHING
456 MOV SI, AX
457 SHL SI, 1
458 INC DOS_REF_COUNT[SI]
459;
460; Update the reference count for the handle and check whether we can close it.
461;
462 MOV SI, MH_DOSHANDLE
463 SHL SI, 1
464 CMP DOS_REF_COUNT[SI], 0
465 JE SHORT MH_CLOSE
466 DEC DOS_REF_COUNT[SI]
467 JNZ SHORT MH_OK
468;
469; The duplicate is no longer referenced, close it now. Note that the
470; handle can only be referenced by P_HANDLES.
471;
472MH_CLOSE: MOV BX, MH_DOSHANDLE
473 MOV AH, 3EH
474 PUSH PROCESS_PTR
475 MOV PROCESS_PTR, NO_PROCESS
476 INT 21H
477 POP PROCESS_PTR
478
479MH_OK: CALL MAYBE_CHECK_HANDLES
480 XOR AX, AX
481MH_RET: MOV SP, BP
482 POP BP
483 POP SI
484 POP DX
485 POP CX
486 POP BX
487 ASSUME BX:NOTHING
488 RET
489
490MH_ERROR: MOV AX, EMFILE ; ENFILE is not implemented
491 STC
492 JMP SHORT MH_RET
493
494MAP_HANDLE ENDP
495
496
497;
498; Update handle translation tables of all processes and other file
499; handles. Also update DOS_REF_COUNT.
500;
501; In: AX Old DOS handle
502; DX New DOS handle
503;
504 TALIGN 4
505 ASSUME DS:SV_DATA
506MAP_TRANSLATE PROC NEAR
507 LEA BX, PROCESS_TABLE
508 ASSUME BX:PTR PROCESS
509 MOV DI, 0 ; Number of changes
510 MOV CX, MAX_PROCESSES + 1 ; Include PROC0 (for OCHAR)!
511MT_LOOP_PROC: MOV SI, 0
512MT_LOOP_HANDLE: CMP [BX].P_HANDLES[SI], AX
513 JNE SHORT MT_NO_UPDATE_1
514 MOV [BX].P_HANDLES[SI], DX
515 INC DI
516MT_NO_UPDATE_1: ADD SI, 2
517 CMP SI, 2 * MAX_FILES
518 JB SHORT MT_LOOP_HANDLE
519 CMP AX, [BX].P_EXEC_HANDLE ; Executable file?
520 JNE SHORT MT_NO_UPDATE_2
521 MOV [BX].P_EXEC_HANDLE, DX
522MT_NO_UPDATE_2: ADD BX, SIZE PROCESS
523 LOOP MT_LOOP_PROC
524;
525; Update DOS_REF_COUNT
526;
527 MOV SI, AX
528 SHL SI, 1
529 SUB DOS_REF_COUNT[SI], DI
530 MOV SI, DX
531 SHL SI, 1
532 ADD DOS_REF_COUNT[SI], DI
533;
534; Update other file handles
535;
536 CMP AX, SWAP_HANDLE ; Swap file?
537 JNE SHORT MT_NO_UPDATE_3
538 MOV SWAP_HANDLE, DX
539MT_NO_UPDATE_3:
540 RET
541 ASSUME BX:NOTHING
542MAP_TRANSLATE ENDP
543
544
545;
546; Remap file handles 0 through 2 of the current process to make the
547; DOS handles identical to the current process' handle. We don't
548; remap all file handles because that would certainly run out of
549; DOS handles: To pass closed handles as closed to the child process,
550; all used handles must be moved out of 0..MAX_FILES-1, leaving no
551; space for non-user handles.
552;
553; In: PROCESS_PTR
554;
555; Out: AX errno if CY is set
556; CY Error
557;
558 TALIGN 4
559 ASSUME DS:SV_DATA
560MAP_ALL_HANDLES PROC NEAR
561 PUSH BX
562 MOV BX, 0
563MAH_LOOP: MOV AX, BX
564 CALL MAP_HANDLE
565 JC SHORT MAH_RET
566 INC BX
567 CMP BX, 3
568 JB SHORT MAH_LOOP
569 XOR AX, AX
570MAH_RET: POP BX
571 RET
572MAP_ALL_HANDLES ENDP
573
574
575;
576; Duplicate inheritable file handles for a child process
577;
578; In: SI Pointer to source process table entry (parent)
579; DI Pointer to destination process table entry (child)
580;
581 ASSUME DS:SV_DATA
582 ASSUME SI:PTR PROCESS
583 ASSUME DI:PTR PROCESS
584INHERIT_HANDLES PROC NEAR
585 MOV BX, 0
586IH_LOOP: MOV AX, [SI].P_HANDLES[BX] ; Get DOS handle
587 MOV DX, [SI].P_HFLAGS[BX] ; Get handle flags
588 TEST DX, HF_NOINHERIT ; Inherit?
589 JNZ SHORT IH_NOINHERIT ; No -> skip
590 CMP AX, NO_FILE_HANDLE ; Valid handle?
591 JE SHORT IH_SET ; No -> don't update ref count
592;
593; Update the reference count
594;
595 PUSH BX
596 MOV BX, AX
597 SHL BX, 1
598 INC DOS_REF_COUNT[BX]
599 POP BX
600;
601; Update the process table entry of the child
602;
603IH_SET: MOV [DI].P_HANDLES[BX], AX
604 MOV [DI].P_HFLAGS[BX], DX
605 JMP SHORT IH_NEXT
606
607;
608; Don't inherit the file handle
609;
610IH_NOINHERIT: MOV AX, NO_FILE_HANDLE
611 MOV DX, 0
612 JMP SHORT IH_SET
613
614;
615; Process next file handle
616;
617IH_NEXT: ADD BX, 2
618 CMP BX, 2 * MAX_FILES
619 JB IH_LOOP
620;
621; Redirect stderr to stdout if the -e option is given
622;
623 TEST [DI].P_FLAGS, PF_REDIR_STDERR ; Redirect stderr?
624 JE SHORT IH_DONT_REDIR ; No -> skip
625 MOV AX, 1 ; stdout
626 MOV CX, 2 ; stderr
627 MOV BX, DI
628 CALL DO_DUP2
629IH_DONT_REDIR: RET
630 ASSUME SI:NOTHING
631 ASSUME DI:NOTHING
632INHERIT_HANDLES ENDP
633
634;
635; Close all open file handles of a process
636;
637; In: BX Pointer to process table entry
638;
639 ASSUME DS:SV_DATA
640 ASSUME BX:PTR PROCESS
641CLOSE_HANDLES PROC NEAR
642 PUSH SI
643 MOV SI, 0
644CH_LOOP: MOV AX, SI
645 CALL DO_CLOSE
646 INC SI
647 CMP SI, MAX_FILES
648 JB CH_LOOP
649 POP SI
650 RET
651 ASSUME BX:NOTHING
652CLOSE_HANDLES ENDP
653
654;
655; Dump handle tables for debugging
656;
657 IF FALSE
658 ASSUME DS:SV_DATA
659DUMP_HANDLES PROC NEAR
660 PUSHA
661 LEA BX, PROCESS_TABLE
662 ASSUME BX:PTR PROCESS
663 MOV CL, 0
664DH_LOOP_PROC: MOV SI, 0
665 MOV AL, "0"
666 CMP CL, MAX_PROCESSES
667 JE SHORT DH_PROC0
668 MOV AL, CL
669 ADD AL, "1"
670DH_PROC0: CALL OCHAR
671 MOV Al, ":"
672 CALL OCHAR
673 MOV AL, " "
674 CALL OCHAR
675DH_LOOP_HANDLE: MOV AX, [BX].P_HANDLES[SI]
676 CMP AX, NO_FILE_HANDLE
677 JE SHORT DH_NO_HANDLE
678 AAM
679 XCHG AL, AH
680 ADD AL, "0"
681 CALL OCHAR
682 XCHG AL, AH
683 ADD AL, "0"
684 CALL OCHAR
685 JMP SHORT DH_NEXT_HANDLE
686
687DH_NO_HANDLE: MOV AL, "-"
688 CALL OCHAR
689 CALL OCHAR
690DH_NEXT_HANDLE: MOV AL, " "
691 CALL OCHAR
692 ADD SI, 2
693 CMP SI, 2 * 24
694 JB SHORT DH_LOOP_HANDLE
695 CALL OCRLF
696 ADD BX, SIZE PROCESS
697 INC CL
698 CMP CL, MAX_PROCESSES + 1 ; Include PROC0
699 JB SHORT DH_LOOP_PROC
700 POPA
701 ASSUME BX:NOTHING
702 RET
703DUMP_HANDLES ENDP
704
705 ENDIF
706
707;
708; Check reference counts
709;
710 ASSUME DS:SV_DATA
711CHECK_HANDLES PROC NEAR
712 PUSHF
713 PUSHA
714 MOV AX, 0
715CH_LOOP_REF: MOV DX, 0
716 MOV CX, MAX_PROCESSES + 1 ; Include PROC0
717 LEA BX, PROCESS_TABLE
718 ASSUME BX:PTR PROCESS
719CH_LOOP_PROC: MOV SI, 0
720CH_LOOP_HANDLE: CMP AX, [BX].P_HANDLES[SI]
721 JNE SHORT CH_NEXT_HANDLE
722 INC DX
723CH_NEXT_HANDLE: ADD SI, 2
724 CMP SI, 2 * MAX_FILES
725 JB SHORT CH_LOOP_HANDLE
726 ADD BX, SIZE PROCESS
727 LOOP CH_LOOP_PROC
728 MOV DI, AX
729 SHL DI, 1
730 CMP DOS_REF_COUNT[DI], DX
731 JNE SHORT CH_FAILURE
732 INC AX
733 CMP AX, TOTAL_FILES
734 JB CH_LOOP_REF
735 ASSUME BX:NOTHING
736CH_RET: POPA
737 POPF
738 RET
739CH_FAILURE: LEA EDX, $CHECK_HANDLES
740 CALL OTEXT
741 CALL OCRLF
742 JMP SHORT CH_RET
743CHECK_HANDLES ENDP
744
745;
746; Call CHECK_HANDLES for -!1
747;
748 TALIGN 4
749 ASSUME DS:SV_DATA
750MAYBE_CHECK_HANDLES PROC NEAR
751 TEST TEST_FLAGS, TEST_CHECK_HANDLES
752 JZ SHORT FIN
753 CALL CHECK_HANDLES
754FIN: RET
755MAYBE_CHECK_HANDLES ENDP
756
757
758;
759; Truncate a path name
760;
761; In: ES:EDI Pathname
762; PROCESS_PTR Pointer to process table entry
763;
764
765 ASSUME DS:SV_DATA
766 TALIGN 4
767TRUNCATE PROC NEAR
768 PUSHAD
769 PUSH FS
770 MOV BX, PROCESS_PTR ; Get PTE of current process
771 CMP BX, NO_PROCESS ; Is there a current process?
772 JE TRUNC_NO ; No -> do nothing
773 MOV ECX, -1 ; Drive letter unknown
774 MOV AL, ES:[EDI] ; Does the pathname start
775 CMP AL, "/" ; with / or \ ?
776 JE SHORT TRUNC_1 ; Yes -> look for special name
777 CMP AL, "\"
778 JNE SHORT TRUNC_CHECK ; No -> skip
779TRUNC_1: MOV AL, ES:[EDI+1] ; Check for UNC pathname
780 CMP AL, "/"
781 JE SHORT TRUNC_UNC ; Yes -> UNC
782 CMP AL, "\"
783 JE SHORT TRUNC_UNC ; Yes -> UNC
784 LEA BX, $DIR_DEV
785 CALL DIR_CHECK ; \dev\ ?
786 JZ TRUNC_NO ; Yes -> do nothing
787 LEA BX, $DIR_PIPE ; (TODO: This is DOS, not OS/2)
788 CALL DIR_CHECK ; \pipe\ ?
789 JZ TRUNC_NO ; Yes -> do nothing
790;
791; We have a pathname that starts with / or \ and is not special. Prepend
792; the drive letter defined by the -r option, if -r is given.
793;
794 MOV BX, PROCESS_PTR ; Get PTE of current process
795 ASSUME BX:PTR PROCESS
796 CMP [BX].P_DRIVE, 0 ; Prepend drive?
797 JE SHORT TRUNC_CHECK ; No ->
798;
799; Prepend drive letter
800;
801 MOV DL, [BX].P_DRIVE ; Get drive letter (A-Z)
802 MOV CL, DL
803 AND ECX, 1FH ; Bit for -t option
804 ASSUME BX:NOTHING
805 MOV DH, ":" ; Insert drive and colon
806 PUSH EDI
807DRIVE_MOVE: MOV AL, DL ; Insert two bytes
808 XCHG DL, ES:[EDI]
809 INC EDI
810 XCHG DL, DH
811 TEST AL, AL
812 JNZ SHORT DRIVE_MOVE
813 POP EDI
814 JMP SHORT TRUNC_CHECK
815
816;
817; It's a UNC pathname
818;
819TRUNC_UNC: MOV ECX, 0 ; Check bit 0
820 JMP SHORT TRUNC_CHECK
821
822;
823; Check if we should truncate the pathname.
824;
825TRUNC_CHECK: MOV BX, PROCESS_PTR ; Get PTE of current process
826 ASSUME BX:PTR PROCESS
827 CMP [BX].P_TRUNC, 0 ; Never truncate?
828 JE TRUNC_NO ; Yes -> do nothing
829 CMP [BX].P_TRUNC, -1 ; Always truncate?
830 JE SHORT TRUNC_YES ; Yes -> truncate
831 CMP ECX, -1 ; Drive known?
832 JNE SHORT TRUNC_CHECK_2 ; Yes -> skip
833;
834; Try to get the drive letter from the pathname
835;
836 MOV AL, ES:[EDI]
837 SUB AL, "A"
838 CMP AL, 26
839 JB SHORT TRUNC_CHECK_1
840 MOV AL, ES:[EDI]
841 SUB AL, "a"
842 CMP AL, 26
843 JAE SHORT TRUNC_CURDISK
844TRUNC_CHECK_1: CMP BYTE PTR ES:[EDI+1], ":"
845 JE SHORT TRUNC_PLUS1
846;
847; We don't know the drive letter -- use the current disk
848;
849TRUNC_CURDISK: MOV AH, 19H
850 INT 21H
851TRUNC_PLUS1: MOV CL, AL
852 INC CL
853 AND ECX, 1FH
854;
855; Check the bit specified by ECX
856;
857TRUNC_CHECK_2: BT [BX].P_TRUNC, ECX ; Truncate for this drive?
858 JNC SHORT TRUNC_NO ; No -> do nothing
859 ASSUME BX:NOTHING
860TRUNC_YES: PUSH DS
861 MOV ESI, EDI ; Setup source pointer
862 MOV_FS_DS ; Access DBCS_LEAD_TAB with FS
863 ASSUME FS:SV_DATA
864 MOV_DS_ES
865 ASSUME DS:NOTHING
866 JMP SHORT TRUNC_NAME ; At start of name
867
868 TALIGN 4
869TRUNC_LOOP: LODS BYTE PTR DS:[ESI] ; Fetch character
870 TEST AL, AL ; End?
871 JE SHORT TRUNC_END ; Yes -> done
872 CMP AL, ":"
873 JE SHORT TRUNC_DIR
874 CMP AL, "\"
875 JE SHORT TRUNC_DIR
876 CMP AL, "/"
877 JE SHORT TRUNC_DIR
878 CMP AL, "."
879 JE SHORT TRUNC_EXT
880 MOV AH, 0
881 BT DBCS_LEAD_TAB, AX ; DBCS lead byte?
882 JC SHORT TRUNC_DBCS
883TRUNC_STORE: TEST CL, CL ; Beyond maximum length?
884 JZ SHORT TRUNC_LOOP ; Yes -> don't store
885 STOS BYTE PTR ES:[EDI] ; Store character
886 DEC CL ; Adjust length counter
887 JMP SHORT TRUNC_LOOP ; Next character
888
889TRUNC_DBCS: CMP BYTE PTR DS:[ESI], 0 ; Invalid DBCS char?
890 JE SHORT TRUNC_STORE ; Yes -> store anyway
891 INC ESI ; Skip 2nd byte
892 CMP CL, 2 ; Can we store 2 bytes?
893 JB SHORT TRUNC_LOOP ; No -> drop both bytes
894 STOS BYTE PTR ES:[EDI] ; Store 1st byte
895 MOV AL, DS:[ESI-1]
896 STOS BYTE PTR ES:[EDI] ; Store 2nd byte
897 SUB CL, 2 ; Adjust length counter
898 JMP SHORT TRUNC_LOOP ; Next character
899
900TRUNC_DIR: STOS BYTE PTR ES:[EDI] ; Store character
901TRUNC_NAME: MOV CX, 0008H ; Extension not seen, 8 chars
902 JMP SHORT TRUNC_LOOP ; Next character
903
904TRUNC_EXT: CMP CX, 0103H ; Previous character a dot?
905 JE SHORT TRUNC_DOTS ; Yes -> keep ".."
906 TEST CH, CH ; Extension seen?
907 JNZ SHORT TRUNC_STOP ; Yes -> stop storing
908TRUNC_DOTS: STOS BYTE PTR ES:[EDI] ; Store dot character
909 MOV CX, 0103H ; Extension seen, 3 characters
910 JMP SHORT TRUNC_LOOP ; Next character
911
912TRUNC_STOP: MOV CL, 0 ; Don't store characters
913 JMP SHORT TRUNC_LOOP ; Next character
914
915TRUNC_END: STOS BYTE PTR ES:[EDI]
916 POP DS
917TRUNC_NO: POP FS
918 POPAD
919 RET
920TRUNCATE ENDP
921
922 ASSUME FS:NOTHING
923
924 TALIGN 4
925DIR_CHECK PROC NEAR
926 PUSH EDI
927DIR_CHECK_1: INC EDI
928 MOV AL, ES:[EDI]
929 CMP BYTE PTR [BX], 0
930 JE SHORT DIR_CHECK_2
931 CALL UPPER
932 CMP AL, [BX]
933 JNE SHORT DIR_CHECK_8
934 INC BX
935 JMP SHORT DIR_CHECK_1
936
937DIR_CHECK_2: CMP AL, "/"
938 JE SHORT DIR_CHECK_8
939 CMP AL, "\"
940DIR_CHECK_8: POP EDI
941 RET
942DIR_CHECK ENDP
943
944SV_CODE ENDS
945
946
947INIT_CODE SEGMENT
948
949 ASSUME CS:INIT_CODE, DS:NOTHING
950
951;
952; Initialize the DOS_REF_COUNT table and the file handles of PROC0.
953;
954; To speed things up, assume that at most handles 0, 1, and 2 are
955; inherited.
956;
957 ASSUME DS:SV_DATA
958INIT_FILEIO PROC NEAR
959;
960; Initially, no file is referenced.
961;
962 MOV BX, 0
963IF_ZERO_REF: MOV DOS_REF_COUNT[BX], 0
964 ADD BX, 2
965 CMP BX, 2 * TOTAL_FILES
966 JB IF_ZERO_REF
967;
968; Initialize the P_HANDLES array of PROC0, setting reference counts
969; as required.
970;
971 MOV BX, 0 ; File handle
972 MOV DI, 0 ; Index
973IF_LOOP: MOV PROC0.P_HFLAGS[DI], 0 ; Clear handle flags
974 MOV AX, 4400H ; Get device data
975 INT 21H
976 JC SHORT IF_NOT_OPEN
977 MOV PROC0.P_HANDLES[DI], BX
978 INC DOS_REF_COUNT[DI]
979 JMP SHORT IF_NEXT
980
981IF_NOT_OPEN: MOV PROC0.P_HANDLES[DI], NO_FILE_HANDLE
982IF_NEXT: ADD DI, 2
983 INC BX
984 CMP BX, MAX_FILES ; File handles per process!
985 JB SHORT IF_LOOP
986 RET
987INIT_FILEIO ENDP
988
989INIT_CODE ENDS
990
991 END
Note: See TracBrowser for help on using the repository browser.