about summary refs log tree commit diff stats
path: root/subx/062write-stream.subx
diff options
context:
space:
mode:
Diffstat (limited to 'subx/062write-stream.subx')
-rw-r--r--subx/062write-stream.subx22
1 files changed, 21 insertions, 1 deletions
diff --git a/subx/062write-stream.subx b/subx/062write-stream.subx
index 73766fe3..92c67dc2 100644
--- a/subx/062write-stream.subx
+++ b/subx/062write-stream.subx
@@ -21,7 +21,7 @@ write-stream:  # f : fd or (address stream), s : (address stream) -> <void>
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
     # if (f < 0x08000000) _write-stream(f, s), return  # f can't be a user-mode address, so treat it as a kernel file descriptor
     81          7/subop/compare     1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         0x08000000/imm32  # compare *(EBP+8)
-    7d/jump-if-greater-or-equal  $write-stream:fake/disp8
+    73/jump-if-greater-unsigned-or-equal  $write-stream:fake/disp8
     # . . push args
     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
@@ -102,6 +102,11 @@ _write-stream:  # fd : int, s : (address stream) -> <void>
     # . . syscall
     b8/copy-to-EAX  4/imm32/write
     cd/syscall  0x80/imm8
+    # if (EAX < 0) abort
+    3d/compare-EAX-with  0/imm32
+    0f 8c/jump-if-lesser  $_write-stream:abort/disp32
+    # s->read += EAX
+    01/add                          1/mod/*+disp8   6/rm32/ESI    .           .             .           0/r32/EAX   4/disp8         .                 # add EAX to *(ESI+4)
     # . restore registers
     5f/pop-to-EDI
     5e/pop-to-ESI
@@ -114,6 +119,21 @@ _write-stream:  # fd : int, s : (address stream) -> <void>
     5d/pop-to-EBP
     c3/return
 
+$_write-stream:abort:
+    # . _write(2/stderr, error)
+    # . . push args
+    68/push  "_write-stream: failed to write to file"/imm32
+    68/push  2/imm32/stderr
+    # . . call
+    e8/call  _write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . syscall(exit, 1)
+    bb/copy-to-EBX  1/imm32
+    b8/copy-to-EAX  1/imm32/exit
+    cd/syscall  0x80/imm8
+    # never gets here
+
 test-write-stream-single:
     # setup
     # . clear-stream(_test-stream)