summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2019-03-21 21:07:49 -0400
committerDrew DeVault <sir@cmpwn.com>2019-03-21 21:07:49 -0400
commitd97cdde38dfaf8d7f63d5f86eb9eac4eab359dc4 (patch)
tree2b24c171826ae8fcb26a7d97d06391f0af9b3d1d
parent0b26241b42153e83eec9a0333d138f4972fd59ab (diff)
downloadaerc-d97cdde38dfaf8d7f63d5f86eb9eac4eab359dc4.tar.gz
Skip writes if term is closed
-rw-r--r--trace499
-rw-r--r--widgets/terminal.go2
2 files changed, 1 insertions, 500 deletions
diff --git a/trace b/trace
deleted file mode 100644
index 0d7af61..0000000
--- a/trace
+++ /dev/null
@@ -1,499 +0,0 @@
-11330 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11330 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340f\0\0\0\0\0\0"..., 832) = 832
-11330 read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
-11330 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000C\2\0\0\0\0\0"..., 832) = 832
-11330 read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\201\336\t\36\251c\324\233E\371SoK\5H\334"..., 68) = 68
-11330 read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\201\336\t\36\251c\324\233E\371SoK\5H\334"..., 68) = 68
-11330 read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
-11330 read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\0\0\0\5\0\0\0\0"..., 4096) = 3536
-11330 read(3, "", 4096)                 = 0
-11330 read(3, "#\n# aerc main configuration\n\n[ui"..., 4096) = 3338
-11330 read(3, "", 4096)                 = 0
-11330 read(3, "#\n# aerc accounts configuration\n"..., 4096) = 566
-11330 read(3, "", 4096)                 = 0
-11330 read(3, "# Binds are of the form <key seq"..., 4096) = 997
-11330 read(3, "", 4096)                 = 0
-11339 read(7, "0-7\n", 8192)            = 4
-11336 read(6, "# Name Service Switch configurat"..., 1024) = 334
-11336 read(6, "", 1024)                 = 0
-11336 read(6, "# Generated by resolvconf\nnamese"..., 65536) = 46
-11336 read(6, "", 65490)                = 0
-11336 read(6, "", 65536)                = 0
-11336 read(6, "# Name Service Switch configurat"..., 4096) = 334
-11336 read(6, "", 4096)                 = 0
-11336 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 0\0\0\0\0\0\0"..., 832) = 832
-11339 read(3, 0xc00009ed80, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11336 read(6, "# Full data: /usr/share/iana-etc"..., 4096) = 4096
-11336 read(6, "          101/udp\niso-tsap      "..., 4096) = 4096
-11336 read(6, "udp\nbgp               179/sctp\nr"..., 4096) = 4096
-11336 read(6, "ogic     313/tcp\nmagenta-logic  "..., 4096) = 4096
-11336 read(6, "dp\nprm-nm            409/tcp\nprm"..., 4096) = 4096
-11336 read(6, "        486/udp\nsaft            "..., 4096) = 4096
-11336 read(6, "p\nwhoami            565/tcp\nwhoa"..., 4096) = 4096
-11336 read(6, "      644/tcp\ndwr               "..., 4096) = 4096
-11336 read(6, "kerberos-adm      749/udp\nrfile "..., 4096) = 4096
-11336 read(6, "# Configuration for getaddrinfo("..., 4096) = 2584
-11336 read(6, "", 4096)                 = 0
-11336 read(6, "# Resolver configuration file.\n#"..., 4096) = 73
-11336 read(6, "", 4096)                 = 0
-11336 read(6, "# Generated by resolvconf\nnamese"..., 4096) = 46
-11336 read(6, "", 4096)                 = 0
-11336 read(6, "# Static table lookup for hostna"..., 4096) = 551
-11336 read(6, "", 4096)                 = 0
-11336 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 `\0\0\0\0\0\0"..., 832) = 832
-11336 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11336 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 `\0\0\0\0\0\0"..., 832) = 832
-11336 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11336 read(6, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 @\0\0\0\0\0\0"..., 832) = 832
-11339 read(6, 0xc0002de000, 517)        = -1 EAGAIN (Resource temporarily unavailable)
-11340 read(6, "\26\3\3\0]\2\0\0Y\3\3\323\257\347\202\253siA}\215\212\255\322\5Hm{\367\362dL"..., 517) = 517
-11340 read(6, "\321\253\326\330@\27\314\16m\4\24038\251\237\262\r\264\361\254\333i_\35\223\23\376\2509\0\0/"..., 2347) = 931
-11340 read(6, 0xc0002f2546, 1416)       = -1 EAGAIN (Resource temporarily unavailable)
-11340 read(6, "\364]f\3701`\210oZ\3550'\n0\r\6\t*\206H\206\367\r\1\1\v\5\0\3\202\1\1"..., 1416) = 859
-11340 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11337 read(6, "\24\3\3\0\1\1\26\3\3\0(EY\230\37\332v]\237m\17Q\335\v\322[\25\303\211\375@,"..., 2766) = 51
-11337 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11339 read(6, "\27\3\3\0\212EY\230\37\332v]\240Ku\347\221\252=\270\10\217\4\317\22\0K;G%\36\25"..., 2766) = 143
-11339 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11338 read(6, "\27\3\3\1\206EY\230\37\332v]\241?u\36D\312\314\303\265\r\17B\347y\f\203\334\345\316j"..., 2766) = 395
-11338 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11336 read(6, "\27\3\3\2\24EY\230\37\332v]\242\211\264w\202\265lOEJ-\344y\274\304\310\373\2\353\325"..., 2766) = 537
-11336 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11337 read(6, "\27\3\3\4\fEY\230\37\332v]\243\2745o \30\333\30ZBn_\24\242N\361\230\322\354\252"..., 2766) = 1041
-11338 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11341 read(6, "\27\3\3\0024EY\230\37\332v]\244\356|\246\2032n\242y\356\367\227Y\245\321\205\330\343\252\301"..., 2766) = 569
-11341 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11336 read(6, "\27\3\3\0pEY\230\37\332v]\245\257\325D\205{sJ\379\246\365<\324R\0265?7\274"..., 2766) = 117
-11336 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11336 read(6, "\27\3\3\10\272EY\230\37\332v]\246;+s\362pF\262Lk@-o\36V\314\241\335\306^"..., 2766) = 2239
-11333 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11338 read(6, "\27\3\3\0IEY\230\37\332v]\247\375'\216N\203#\375U\2512L\35\273%\236q\244\270\252"..., 2766) = 78
-11338 read(6, 0xc0002f2000, 2766)       = -1 EAGAIN (Resource temporarily unavailable)
-11338 read(3, "$", 128)                 = 1
-11338 read(3, 0xc0002f0600, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11333 read(3, "v", 128)                 = 1
-11333 read(3, 0xc0002f0680, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11333 read(3, "i", 128)                 = 1
-11333 read(3, 0xc00039e000, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11333 read(3, "m", 128)                 = 1
-11333 read(3, 0xc00039e080, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11333 read(3, "\r", 128)                = 1
-11333 read(3, 0xc00039e100, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11341 read(9, "", 8)                    = 0
-11334 read(7,  <unfinished ...>
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 @\10\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \240\2\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 P\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \320\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \1\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 `\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 `\3\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \340\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \260\1\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0PH\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220 \1\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \300\1\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \320\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 p\1\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\30\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340f\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
-11347 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000C\2\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\201\336\t\36\251c\324\233E\371SoK\5H\334"..., 68) = 68
-11347 read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\201\336\t\36\251c\324\233E\371SoK\5H\334"..., 68) = 68
-11347 read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 0\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\24\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 @\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \260\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \300\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \320\5\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\22\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \240\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 p\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \200\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \320\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\200\n\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 0\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 P\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 `\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 @\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \260\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 `\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \300\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 `\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320!\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \300\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 @\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@ \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320\21\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \340\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \0\1\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 0\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 @\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000\21\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \240\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 \20\1\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300,\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0  \0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@\300\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 @\0\0\0\0\0\0"..., 832) = 832
-11347 read(3, "# Locale name alias data base.\n#"..., 4096) = 2997
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\36\2%\0&\0\17\0\235\1\2\6xterm-256color|xterm"..., 32768) = 3713
-11347 read(3, "", 28672)                = 0
-11347 read(3, "\" All system-wide defaults are s"..., 4096) = 912
-11347 read(4, "\" The Arch Linux global vimrc - "..., 4096) = 1423
-11347 read(4, "", 4096)                 = 0
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "set nocompatible\nfiletype off\n\ns"..., 4096) = 4096
-11347 read(4, "\" Vim support file to switch off"..., 4096) = 280
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\" Vundle        is a shortcut fo"..., 4096) = 3800
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\" ------------------------------"..., 4096) = 4096
-11347 read(4, "be supplied with the bundle spec"..., 4096) = 4096
-11347 read(4, " the corresponding 'after' direc"..., 4096) = 2323
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\" Vim support file to detect fil"..., 4096) = 4096
-11347 read(4, " getline(1) . getline(2) . getli"..., 4096) = 4096
-11347 read(4, "libs\nau BufNewFile,BufRead *.tlh"..., 4096) = 4096
-11347 read(4, "tch\n\t\\ if getline(1) =~ '^From ["..., 4096) = 4096
-11347 read(4, "  \\ if getline(1) =~ '^From.*# T"..., 4096) = 4096
-11347 read(4, "usw2kagtlog\n\n\" Ipfilter\nau BufNe"..., 4096) = 4096
-11347 read(4, ",BufRead .mailcap,mailcap\t\tsetf "..., 4096) = 4096
-11347 read(4, " omnimark\n\n\" OpenROAD\nau BufNewF"..., 4096) = 4096
-11347 read(4, "and Python Stub Files\n\" Quixote "..., 4096) = 4096
-11347 read(4, ") =~ '<!DOCTYPE.*DocBook' || get"..., 4096) = 4096
-11347 read(4, "Read *.ado,*.do,*.imata,*.mata\ts"..., 4096) = 4096
-11347 read(4, "l Basic (also uses *.bas) or FOR"..., 4096) = 4096
-11347 read(4, "age template)\nau BufNewFile,BufR"..., 4096) = 4096
-11347 read(4, "etf('muttrc')\nau BufNewFile,BufR"..., 4096) = 4096
-11347 read(5, "autocmd BufReadPost *.fugitivebl"..., 4096) = 62
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "if !has('patch-7.4.480')\n    \" B"..., 4096) = 362
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" Go dep and Rust use several TO"..., 4096) = 190
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" vint: -ProhibitAutocmdWithNoGr"..., 4096) = 195
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\""..., 4096) = 1261
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "fun! s:SelectJavascript()\n  if g"..., 4096) = 316
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" Language:    CoffeeScript\n\" Ma"..., 4096) = 552
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" Language:   Literate CoffeeScr"..., 4096) = 299
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" Copyright 2014 Google Inc. All"..., 4096) = 699
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "au BufRead,BufNewFile *.scad    "..., 4096) = 114
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" use `set filetype` to override"..., 4096) = 255
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "if !exists('g:glsl_default_versi"..., 4096) = 1207
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "autocmd BufRead,BufNewFile *.gd "..., 4096) = 55
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "autocmd BufRead,BufNewFile *.sha"..., 4096) = 53
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "au BufNewFile,BufRead PKGBUILD s"..., 4096) = 53
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "au BufNewFile,BufRead *.aug set "..., 4096) = 48
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "au BufNewFile,BufRead [Dd]ockerf"..., 4096) = 92
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "au BufNewFile,BufRead meson.buil"..., 4096) = 112
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "au BufRead,BufNewFile *.nginx se"..., 4096) = 198
-11347 read(5, "", 4096)                 = 0
-11347 read(4, "tore 'cpoptions'\nlet &cpo = s:cp"..., 4096) = 56
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\" Vim support file to switch on "..., 4096) = 971
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\" Vim support file to switch on "..., 4096) = 767
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\" Vim syntax support file\n\" Main"..., 4096) = 1228
-11347 read(5, "\" Vim syntax support file\n\" Main"..., 4096) = 1984
-11347 read(6, "\" Vim syntax support file\n\" Main"..., 4096) = 4093
-11347 read(7, "255 250 250\t\tsnow\n248 248 255\t\tg"..., 4096) = 4096
-11347 read(7, "dYellow\n255 255 224\t\tlight yello"..., 4096) = 4096
-11347 read(7, "8\t\tLightBlue2\n154 192 205\t\tLight"..., 4096) = 4096
-11347 read(7, "1 159\t\tPaleVioletRed2\n205 104 13"..., 4096) = 4096
-11347 read(7, "9 199 199\t\tgray78\n199 199 199\t\tg"..., 4096) = 1396
-11347 read(7, "", 4096)                 = 0
-11347 read(7, "255 250 250\t\tsnow\n248 248 255\t\tg"..., 4096) = 4096
-11347 read(7, "dYellow\n255 255 224\t\tlight yello"..., 4096) = 4096
-11347 read(7, "8\t\tLightBlue2\n154 192 205\t\tLight"..., 4096) = 4096
-11347 read(7, "1 159\t\tPaleVioletRed2\n205 104 13"..., 4096) = 4096
-11347 read(7, "9 199 199\t\tgray78\n199 199 199\t\tg"..., 4096) = 1396
-11347 read(7, "", 4096)                 = 0
-11347 read(6, "", 4096)                 = 0
-11347 read(5, "", 4096)                 = 0
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\" Vim syntax support file\n\" Main"..., 4096) = 1228
-11347 read(5, "\" Vim syntax support file\n\" Main"..., 4096) = 755
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" Vim syntax support file\n\" Main"..., 4096) = 1984
-11347 read(6, "\" Vim syntax support file\n\" Main"..., 4096) = 4093
-11347 read(6, "", 4096)                 = 0
-11347 read(5, "", 4096)                 = 0
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\" local syntax file - set colors"..., 4096) = 1393
-11347 read(5, "\" Vim syntax support file\n\" Main"..., 4096) = 4093
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" Vim syntax support file\n\" Main"..., 4096) = 4093
-11347 read(5, "", 4096)                 = 0
-11347 read(5, "\" Vim syntax support file\n\" Main"..., 4096) = 4093
-11347 read(5, "", 4096)                 = 0
-11347 read(4, "", 4096)                 = 0
-11347 read(3, "FileReadPre *.gpg set noswapfile"..., 4096) = 661
-11347 read(3, "", 4096)                 = 0
-11347 read(4, "\" Adapted from unimpaired.vim by"..., 4096) = 3861
-11347 read(4, "", 4096)                 = 0
-11347 read(3, "\" fugitive.vim - A Git wrapper s"..., 4096) = 4096
-11347 read(3, "fugitive:'\n    return matchstr(p"..., 4096) = 4096
-11347 read(3, " if FugitiveIsGitDir(expand('<am"..., 4096) = 1004
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" =============================="..., 4096) = 2481
-11347 read(4, "\" =============================="..., 4096) = 4064
-11347 read(4, "", 4096)                 = 0
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" surround.vim - Surroundings\n\" "..., 4096) = 4096
-11347 read(3, "if\n      let default = matchstr("..., 4096) = 4096
-11347 read(3, "ile char == \"\\<CR>\" || char == \""..., 4096) = 4096
-11347 read(3, "special)\n  endif\n  silent exe 'n"..., 4096) = 4096
-11347 read(3, " ! g:surround_no_mappings\n  nmap"..., 4096) = 619
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" Copyright (c) 2011-2015 Editor"..., 4096) = 4096
-11347 read(3, "          \\ '/usr/bin/python24']"..., 4096) = 4096
-11347 read(3, "if\n\n    \" Find python interp\n   "..., 4096) = 4096
-11347 read(3, "ath, ':h')\n        if l:path == "..., 4096) = 4096
-11347 read(3, " l:eq_left = strpart(one_line, 0"..., 4096) = 4096
-11347 read(3, "                    \" Fill only "..., 4096) = 1362
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" SyntaxRange.vim: Define a diff"..., 4096) = 1045
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "if exists('g:loaded_rust_vim_plu"..., 4096) = 955
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" Vim syntastic plugin helper\n\" "..., 4096) = 718
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\n\n\" A plugin for jsonnet files.\n"..., 4096) = 723
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" ------------------------------"..., 4096) = 1393
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" Vim plugin for editing compres"..., 4096) = 2499
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" LogiPat: Boolean logical patte"..., 4096) = 4096
-11347 read(3, "  let s:nopstack= 0\n  endif\n\n  \""..., 4096) = 4096
-11347 read(3, "tern {{{2\nfun! s:LP_Not(pat)\n\"  "..., 4096) = 2077
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" Vim plugin for using Vim as ma"..., 4096) = 676
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" Vim plugin for showing matchin"..., 4096) = 4096
-11347 read(3, "ne = stoplinetop\n  endif\n\n  \" Li"..., 4096) = 2989
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" netrwPlugin.vim: Handles file "..., 4096) = 4096
-11347 read(3, ">0,<q-args>)\ncom! -nargs=* -bar "..., 4096) = 4096
-11347 read(3, "      listing when appropriate.\n"..., 4096) = 2248
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" Vim plugin with helper functio"..., 4096) = 1414
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" Vim plugin for downloading spe"..., 4096) = 499
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" tarPlugin.vim -- a Vim plugin "..., 4096) = 2271
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" Vim plugin for converting a sy"..., 4096) = 4096
-11347 read(3, "' for converted document encodin"..., 4096) = 4096
-11347 read(3, " html_prevent_copy contains\n\"   "..., 4096) = 2274
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" vimballPlugin : construct a fi"..., 4096) = 2898
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "\" zipPlugin.vim: Handles browsin"..., 4096) = 2510
-11347 read(3, "", 4096)                 = 0
-11347 read(3, "# This viminfo file was generate"..., 4096) = 4096
-11347 read(3, "9919,47,\"SelectedTab\"\n?/Global\n|"..., 4096) = 4096
-11347 read(3, " drown in emails...\n\t> \n\t> Thank"..., 4096) = 4096
-11347 read(3, " At first I wanted to patch teh "..., 4096) = 4096
-11347 read(3, "~/sources/go-libvterm/.git/COMMI"..., 4096) = 4096
-11347 read(3, "/neovim/src/nvim/terminal.c\n|4,3"..., 4096) = 4096
-11347 read(3, "  ~/sources/neovim/src/nvim/term"..., 4096) = 4096
-11347 read(3, "1553214152\t0\n\t\"\t1\t18\n\t^\t1\t19\n\t.\t"..., 4096) = 4096
-11347 read(3, "\"\t219\t0\n\t^\t176\t15\n\t.\t177\t34\n\t+\t1"..., 4096) = 4096
-11347 read(3, "0\n\t^\t1\t15\n\t.\t1\t14\n\t+\t10\t1\n\t+\t1\t1"..., 4096) = 4096
-11347 read(3, "/asdf\n\t*\t1553186123\t0\n\t\"\t1\t0\n\n> "..., 4096) = 1482
-11347 read(3, "", 4096)                 = 0
-11347 read(4, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"..., 4096) = 4096
-11347 read(4, "UTF-8\nbo_IN.utf8\t\t\t\t\tbo_IN.UTF-8"..., 4096) = 4096
-11347 read(4, "\t\t\tde_DE.ISO8859-15\nde_DE.88591\t"..., 4096) = 4096
-11347 read(4, "ES.ISO8859-1\nes.UTF-8\t\t\t\t\tes_ES."..., 4096) = 4096
-11347 read(4, "91\t\t\t\t\tfi_FI.ISO8859-1\nfi_FI.ISO"..., 4096) = 4096
-11347 read(4, "\t\t\t\the_IL.UTF-8\nhi\t\t\t\t\t\thi_IN.IS"..., 4096) = 4096
-11347 read(4, ".ISO8859-13\nlt_LT\t\t\t\t\t\tlt_LT.ISO"..., 4096) = 4096
-11347 read(4, "so88591\t\t\t\t\tpd_DE.ISO8859-1\npd_U"..., 4096) = 4096
-11347 read(4, "s_ZA.ISO8859-1\nss_ZA.iso88591\t\t\t"..., 4096) = 4096
-11347 read(4, "5hkscs\nzh_HK.BIG5-HKSCS\t\t\t\tzh_HK"..., 4096) = 4096
-11347 read(4, "af_ZA.iso88591:\t\t\t\t\taf_ZA.ISO885"..., 4096) = 4096
-11347 read(4, "SO8859-1\nca_AD:\t\t\t\t\t\tca_AD.ISO88"..., 4096) = 4096
-11347 read(4, "\t\t\tde_DE.UTF-8\nde_LU:\t\t\t\t\t\tde_LU"..., 4096) = 4096
-11347 read(4, "8859-1\nes_CL.ISO-8859-1:\t\t\t\tes_C"..., 4096) = 4096
-11347 read(4, "\t\t\tfi_FI.ISO8859-15\nfi_FI.utf8:\t"..., 4096) = 4096
-11347 read(4, "idev:\t\t\t\t\thi_IN.ISCII-DEV\nhi_IN."..., 4096) = 4096
-11347 read(4, "\n\n\n\n\n\n\nlt:\t\t\t\t\t\tlt_LT.ISO8859-13"..., 4096) = 4096
-11347 read(4, "N.UTF-8\npa_IN.utf8:\t\t\t\t\tpa_IN.UT"..., 4096) = 4096
-11347 read(4, "r_RS.UTF-8\nsr@latin:\t\t\t\t\tsr_RS.U"..., 4096) = 4096
-11347 read(4, "ucCN\nzh_CN.GB2312:\t\t\t\t\tzh_CN.gb2"..., 4096) = 3875
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"..., 4096) = 4096
-11347 read(4, "UTF-8\nbo_IN.utf8\t\t\t\t\tbo_IN.UTF-8"..., 4096) = 4096
-11347 read(4, "\t\t\tde_DE.ISO8859-15\nde_DE.88591\t"..., 4096) = 4096
-11347 read(4, "ES.ISO8859-1\nes.UTF-8\t\t\t\t\tes_ES."..., 4096) = 4096
-11347 read(4, "91\t\t\t\t\tfi_FI.ISO8859-1\nfi_FI.ISO"..., 4096) = 4096
-11347 read(4, "\t\t\t\the_IL.UTF-8\nhi\t\t\t\t\t\thi_IN.IS"..., 4096) = 4096
-11347 read(4, ".ISO8859-13\nlt_LT\t\t\t\t\t\tlt_LT.ISO"..., 4096) = 4096
-11347 read(4, "so88591\t\t\t\t\tpd_DE.ISO8859-1\npd_U"..., 4096) = 4096
-11347 read(4, "s_ZA.ISO8859-1\nss_ZA.iso88591\t\t\t"..., 4096) = 4096
-11347 read(4, "5hkscs\nzh_HK.BIG5-HKSCS\t\t\t\tzh_HK"..., 4096) = 4096
-11347 read(4, "af_ZA.iso88591:\t\t\t\t\taf_ZA.ISO885"..., 4096) = 4096
-11347 read(4, "SO8859-1\nca_AD:\t\t\t\t\t\tca_AD.ISO88"..., 4096) = 4096
-11347 read(4, "\t\t\tde_DE.UTF-8\nde_LU:\t\t\t\t\t\tde_LU"..., 4096) = 4096
-11347 read(4, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"..., 4096) = 4096
-11347 read(4, "CALE\t\t\tes_NI.ISO8859-1\niso8859-1"..., 4096) = 4096
-11347 read(4, "E\t\t\tph_PH.ISO8859-1\niso8859-2/XL"..., 4096) = 4096
-11347 read(4, "-8\nen_US.UTF-8/XLC_LOCALE\t\t\ten_B"..., 4096) = 4096
-11347 read(4, "_PT.UTF-8\nen_US.UTF-8/XLC_LOCALE"..., 4096) = 4096
-11347 read(4, "\niso8859-15/XLC_LOCALE:\t\t\tde_CH."..., 4096) = 4096
-11347 read(4, "ALE:\t\t\thu_HU.ISO8859-2\narmscii-8"..., 4096) = 4096
-11347 read(4, "/XLC_LOCALE:\t\t\tzh_CN.eucCN\nzh_CN"..., 4096) = 4096
-11347 read(4, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"..., 4096) = 4096
-11347 read(4, "\n \n#\tcs20 class\ncs15\t{\n\tside\t\tGR"..., 4096) = 155
-11347 read(4, "", 4096)                 = 0
-11334 <... read resumed> "\33[?1000h\33[?2004h", 4096) = 16
-11334 read(7, "\33[?1049h\33[22;0;0t\33[?1h\33=\33[?2004h"..., 4096) = 65
-11334 read(7,  <unfinished ...>
-11347 read(4, "# Name Service Switch configurat"..., 4096) = 334
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0 0\0\0\0\0\0\0"..., 832) = 832
-11347 read(4, "root:x:0:0::/root:/bin/bash\nbin:"..., 4096) = 2333
-11347 read(4, "\" Location:     autoload/fugitiv"..., 4096) = 4096
-11347 read(4, "\n  endtry\nendfunction\n\n\" Section"..., 4096) = 4096
-11347 read(4, "-C ' . s:shellesc(tree) . ' ' . "..., 4096) = 4096
-11347 read(4, "!=# ''\n    if has_key(s:repos, d"..., 4096) = 4096
-11347 read(4, "ile] = s:DirCommitFile(a:url)\n  "..., 4096) = 4096
-11347 read(4, "\\)\\|^:[0-3]:\\%(/\\|\\a\\+:\\)'\n    l"..., 4096) = 4096
-11347 read(4, "'fugitive_blamed_bufnr', '')\n   "..., 4096) = 4096
-11347 read(4, "(tree, path, [])\n  if empty(entr"..., 4096) = 4096
-11347 read(4, "# 'blob'\n    return []\n  endif\n "..., 4096) = 4096
-11347 read(4, "name() which has been removed. R"..., 4096) = 4096
-11347 read(4, "ll map(entries,'s:sub(v:val,\"^04"..., 4096) = 4096
-11347 read(4, "tatus['Unstaged'][files] = line["..., 4096) = 4096
-11347 read(4, ")\n    let nowait = v:version >= "..., 4096) = 4096
-11347 read(4, "ch>')\n  let [dir, rev] = s:DirRe"..., 4096) = 4096
-11347 read(4, "'cat-file', b:fugitive_type, rev"..., 4096) = 4096
-11347 read(4, "\n    else\n      -tabnew\n    endi"..., 4096) = 4096
-11347 read(4, ")\n    if len(filename) &&\n      "..., 4096) = 4096
-11347 read(4, "(\\x\\x\\x\\)\\@!\\l\\+\\ze [0-9a-f]'),\n"..., 4096) = 4096
-11347 read(4, "ion)\n        let status = s:Do{a"..., 4096) = 4096
-11347 read(4, "eturn 'Git! diff --no-ext-diff -"..., 4096) = 4096
-11347 read(4, ") abort\n  exe 'edit' s:fnameesca"..., 4096) = 4096
-11347 read(4, "rgs =~# '\\%(^\\| \\)-\\%(-interacti"..., 4096) = 4096
-11347 read(4, "TCH_HEAD\\nMERGE_HEAD\\nORIG_HEAD\""..., 4096) = 4096
-11347 read(4, "dit\\|--abort\\|-m\\)\\>' || a:cmd ="..., 4096) = 4096
-11347 read(4, "f:%l:%c:%m,%f:%l:%m,%m %f match%"..., 4096) = 4096
-11347 read(4, "ose\n          if winnr('$') > 1\n"..., 4096) = 4096
-11347 read(4, "l s:command(\"-bar -bang -nargs=*"..., 4096) = 4096
-11347 read(4, " restorewinnr = 1\n        endif\n"..., 4096) = 4096
-11347 read(4, "fthis() abort\n  if !&diff\n    le"..., 4096) = 4096
-11347 read(4, "f\n    endif\n    return post\n  ca"..., 4096) = 4096
-11347 read(4, "len(s:gsub(matchstr(getline('.')"..., 4096) = 4096
-11347 read(4, "ve:[\\\\/][\\\\/]\"<Bar>Gedit<Bar>end"..., 4096) = 4096
-11347 read(4, "ameAnnotation,fugitiveblameOrigi"..., 4096) = 4096
-11347 read(4, "\n    else\n      let expanded = s"..., 4096) = 4096
-11347 read(4, "# '^ref: ' && i < 10\n        let"..., 4096) = 4096
-11347 read(4, "U>.,.+2Gblame<CR>\n    else\n     "..., 4096) = 4096
-11347 read(4, "==# 'Unstaged' && info.sigil !=#"..., 4096) = 4096
-11347 read(4, "eif getline('.') =~# '^[+-]' && "..., 4096) = 4096
-11347 read(4, "(...) abort\n  if empty(s:Dir())\n"..., 4096) = 3445
-11347 read(4, "", 4096)                 = 0
-11334 <... read resumed> "\33[27m\33[23m\33[29m\33[m\33[H\33[2J\33[?25l\33"..., 4096) = 2029
-11334 read(7, "\33[25;1H\33[38;5;242m[No Name]     "..., 4096) = 564
-11334 read(7,  <unfinished ...>
-11339 read(3, ":", 128)                 = 1
-11339 read(3, 0xc0002f0000, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11347 read(0, ":", 4096)                = 1
-11334 <... read resumed> "\33[?25l\33[26;1H:", 4096) = 14
-11334 read(7, "\33[?2004h\33[?25h", 4096) = 14
-11334 read(7,  <unfinished ...>
-11333 read(3, "q", 128)                 = 1
-11333 read(3, 0xc0002f0080, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11347 read(0, "q", 4096)                = 1
-11334 <... read resumed> "q\33[?25l\33[?25h", 4096) = 13
-11334 read(7,  <unfinished ...>
-11336 read(3, "!", 128)                 = 1
-11336 read(3, 0xc00009e000, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11347 read(0, "!", 4096)                = 1
-11334 <... read resumed> "!\33[?25l\33[?25h", 4096) = 13
-11334 read(7,  <unfinished ...>
-11336 read(3, "\r", 128)                = 1
-11336 read(3, 0xc0002f0000, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11347 read(0, "\r", 4096)               = 1
-11334 <... read resumed> "\r", 4096)    = 1
-11334 read(7,  <unfinished ...>
-11347 read(4, "\" =============================="..., 4096) = 2886
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "/home/sircmpwn/sources/pangoterm"..., 4096) = 4096
-11347 read(4, "home/sircmpwn/sources/musl/src/i"..., 4096) = 4096
-11347 read(4, "p/mutt-homura-1000-10676-1575043"..., 4096) = 4096
-11347 read(4, "sources/godot/platform/generic-u"..., 4096) = 1059
-11347 read(4, "", 4096)                 = 0
-11347 read(4, "# This viminfo file was generate"..., 4096) = 4096
-11347 read(4, "9919,47,\"SelectedTab\"\n?/Global\n|"..., 4096) = 4096
-11347 read(4, " drown in emails...\n\t> \n\t> Thank"..., 4096) = 4096
-11347 read(4, " At first I wanted to patch teh "..., 4096) = 4096
-11347 read(4, "~/sources/go-libvterm/.git/COMMI"..., 4096) = 4096
-11347 read(4, "/neovim/src/nvim/terminal.c\n|4,3"..., 4096) = 4096
-11347 read(4, "  ~/sources/neovim/src/nvim/term"..., 4096) = 4096
-11347 read(4, "1553214152\t0\n\t\"\t1\t18\n\t^\t1\t19\n\t.\t"..., 4096) = 4096
-11347 read(4, "\"\t219\t0\n\t^\t176\t15\n\t.\t177\t34\n\t+\t1"..., 4096) = 4096
-11347 read(4, "0\n\t^\t1\t15\n\t.\t1\t14\n\t+\t10\t1\n\t+\t1\t1"..., 4096) = 4096
-11347 read(4, "/asdf\n\t*\t1553186123\t0\n\t\"\t1\t0\n\n> "..., 4096) = 1482
-11347 read(4, "", 4096)                 = 0
-11334 <... read resumed> "\33[?25l\33[?1000l\33[?2004l", 4096) = 22
-11334 read(7, "\33[23;2t\33[23;1t\33[22;2t\33[22;1t\33[23"..., 4096) = 97
-11334 read(7, 0xc0003be000, 4096)       = -1 EIO (Input/output error)
-11347 +++ exited with 0 +++
-11334 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=11347, si_uid=1000, si_status=0, si_utime=5, si_stime=3} ---
-11336 read(3, "q", 128)                 = 1
-11336 read(3, 0xc0002f0080, 128)        = -1 EAGAIN (Resource temporarily unavailable)
-11349 +++ exited with 0 +++
-11348 +++ exited with 0 +++
-11340 +++ exited with 0 +++
-11341 +++ exited with 0 +++
-11339 +++ exited with 0 +++
-11338 +++ exited with 0 +++
-11337 +++ exited with 0 +++
-11336 +++ exited with 0 +++
-11335 +++ exited with 0 +++
-11334 +++ exited with 0 +++
-11333 +++ exited with 0 +++
-11332 +++ exited with 0 +++
-11331 +++ exited with 0 +++
-11330 +++ exited with 0 +++
diff --git a/widgets/terminal.go b/widgets/terminal.go
index d817023..5b0be1a 100644
--- a/widgets/terminal.go
+++ b/widgets/terminal.go
@@ -120,7 +120,7 @@ func NewTerminal(cmd *exec.Cmd) (*Terminal, error) {
 		buf := make([]byte, 4096)
 		for {
 			n, err := term.pty.Read(buf)
-			if err != nil {
+			if err != nil || term.closed {
 				// These are generally benine errors when the process exits
 				term.Close(nil)
 				return
ith the address in some register * `*(reg + disp)`: add a constant to the address in some register * `*(base + (index << scale) + disp)` where `base` and `index` are registers, and `scale` and `disp` are 2- and 32-bit constants respectively. Under the hood, SubX turns expressions of these forms into multiple arguments with metadata in some complex ways. See [SubX-addressing-modes.md](SubX-addressing-modes.md). That covers the complexities of the reg/mem operand. The second operand is simpler. It comes from exactly one of the following argument types: - `/r32` - displacement: `/disp8` or `/disp32` - immediate: `/imm8` or `/imm32` Putting all this together, here's an example that adds the integer in `eax` to the one at address `edx`: ``` 01/add %edx 0/r32/eax ``` ## The syntax of SubX programs SubX programs map to the same ELF binaries that a conventional Linux system uses. Linux ELF binaries consist of a series of _segments_. In particular, they distinguish between code and data. Correspondingly, SubX programs consist of a series of segments, each starting with a header line: `==` followed by a name and approximate starting address. All code must lie in a segment called 'code'. Segments can be added to. ```sh == code 0x09000000 # first mention requires starting address ...A... == data 0x0a000000 ...B... == code # no address necessary when adding ...C... ``` The `code` segment now contains the instructions of `A` as well as `C`. Within the `code` segment, each line contains a comment, label or instruction. Comments start with a `#` and are ignored. Labels should always be the first word on a line, and they end with a `:`. Instructions can refer to labels in displacement or immediate arguments, and they'll obtain a value based on the address of the label: immediate arguments will contain the address directly, while displacement arguments will contain the difference between the address and the address of the current instruction. The latter is mostly useful for `jump` and `call` instructions. Functions are defined using labels. By convention, labels internal to functions (that must only be jumped to) start with a `$`. Any other labels must only be called, never jumped to. All labels must be unique. A special label is `Entry`, which can be used to specify/override the entry point of the program. It doesn't have to be unique, and the latest definition will override earlier ones. (The `Entry` label, along with duplicate segment headers, allows programs to be built up incrementally out of multiple [_layers_](http://akkartik.name/post/wart-layers).) The data segment consists of labels as before and byte values. Referring to data labels in either `code` segment instructions or `data` segment values yields their address. Automatic tests are an important part of SubX, and there's a simple mechanism to provide a test harness: all functions that start with `test-` are called in turn by a special, auto-generated function called `run-tests`. How you choose to call it is up to you. I try to keep things simple so that there's less work to do when implementing SubX in SubX. But there _is_ one convenience: instructions can provide a string literal surrounded by quotes (`"`) in an `imm32` argument. SubX will transparently copy it to the `data` segment and replace it with its address. Strings are the only place where a SubX word is allowed to contain spaces. That should be enough information for writing SubX programs. The `apps/` directory provides some fodder for practice in the `apps/ex*` files, giving a more gradual introduction to SubX features. This repo includes binaries for all examples. At any commit, an example's binary should be identical bit for bit with the result of translating the corresponding `.subx` file. The binary should also be natively runnable on a Linux system running on Intel x86 processors, either 32- or 64-bit. If either of these invariants is broken it's a bug on my part. ## Running `subx` currently has the following sub-commands: * `subx help`: some helpful documentation to have at your fingertips. * `subx test`: runs all automated tests. * `subx translate <input files> -o <output ELF binary>`: translates `.subx` files into an executable ELF binary. * `subx run <ELF binary>`: simulates running the ELF binaries emitted by `subx translate`. Useful for testing and debugging. Remember, not all 32-bit Linux binaries are guaranteed to run. I'm not building general infrastructure here for all of the x86 instruction set. SubX is about programming with a small, regular subset of 32-bit x86. ## A few hints for debugging Writing programs in SubX is surprisingly pleasant and addictive. Reading programs is a work in progress, and hopefully the extensive unit tests help. However, _debugging_ programs is where one really faces up to the low-level nature of SubX. Even the smallest modifications need testing to make sure they work. In my experience, there is no modification so small that I get it working on the first attempt. And when it doesn't work, there are no clear error messages. Machine code is too simple-minded for that. You can't use a debugger, since SubX's simplistic ELF binaries contain no debugging information. So debugging requires returning to basics and practicing with a new, more rudimentary but hopefully still workable toolkit: * Start by nailing down a concrete set of steps for reproducibly obtaining the error or erroneous behavior. * If possible, turn the steps into a failing test. It's not always possible, but SubX's primary goal is to keep improving the variety of tests one can write. * Start running the single failing test alone. This involves modifying the top of the program (or the final `.subx` file passed in to `subx translate`) by replacing the call to `run-tests` with a call to the appropriate `test-` function. * Generate a trace for the failing test while running your program in emulated mode (`subx run`): ``` $ ./subx translate input.subx -o binary $ ./subx --trace run binary arg1 arg2 2>trace ``` The ability to generate a trace is the essential reason for the existence of `subx run` mode. It gives far better visibility into program internals than running natively. * As a further refinement, it is possible to render label names in the trace by adding a second flag to both the `translate` and `run` commands: ``` $ ./subx --debug translate input.subx -o binary $ ./subx --debug --trace run binary arg1 arg2 2>trace ``` `subx --debug translate` emits a mapping from label to address in a file called `labels`. `subx --debug --trace run` reads in the `labels` file at the start and prints out any matching label name as it traces each instruction executed. Here's a sample of what a trace looks like, with a few boxes highlighted: <img alt='trace example' src='html/trace.png'> Each of the green boxes shows the trace emitted for a single instruction. It starts with a line of the form `run: inst: ___` followed by the opcode for the instruction, the state of registers before the instruction executes, and various other facts deduced during execution. Some instructions first print a matching label. In the above screenshot, the red boxes show that address `0x0900005e` maps to label `$loop` and presumably marks the start of some loop. Function names get similar `run: == label` lines. * One trick when emitting traces with labels: ``` $ grep label trace ``` This is useful for quickly showing you the control flow for the run, and the function executing when the error occurred. I find it useful to start with this information, only looking at the complete trace after I've gotten oriented on the control flow. Did it get to the loop I just modified? How many times did it go through the loop? * Once you have SubX displaying labels in traces, it's a short step to modify the program to insert more labels just to gain more insight. For example, consider the following function: <img alt='control example -- before' src='html/control0.png'> This function contains a series of jump instructions. If a trace shows `is-hex-lowercase-byte?` being encountered, and then `$is-hex-lowercase-byte?:end` being encountered, it's still ambiguous what happened. Did we hit an early exit, or did we execute all the way through? To clarify this, add temporary labels after each jump: <img alt='control example -- after' src='html/control1.png'> Now the trace should have a lot more detail on which of these labels was reached, and precisely when the exit was taken. * If you find yourself wondering, "when did the contents of this memory address change?", `subx run` has some rudimentary support for _watch points_. Just insert a label starting with `$watch-` before an instruction that writes to the address, and its value will start getting dumped to the trace after every instruction thereafter. * Once we have a sense for precisely which instructions we want to look at, it's time to look at the trace as a whole. Key is the state of registers before each instruction. If a function is receiving bad arguments it becomes natural to inspect what values were pushed on the stack before calling it, tracing back further from there, and so on. I occasionally want to see the precise state of the stack segment, in which case I uncomment a commented-out call to `dump_stack()` in the `vm.cc` layer. It makes the trace a lot more verbose and a lot less dense, necessitating a lot more scrolling around, so I keep it turned off most of the time. * If the trace seems overwhelming, try [browsing it](https://github.com/akkartik/mu/blob/master/tools/browse_trace.readme.md) in the 'time-travel debugger'. Hopefully these hints are enough to get you started. The main thing to remember is to not be afraid of modifying the sources. A good debugging session gets into a nice rhythm of generating a trace, staring at it for a while, modifying the sources, regenerating the trace, and so on. Email [me](mailto:mu@akkartik.com) if you'd like another pair of eyes to stare at a trace, or if you have questions or complaints. ## Reference documentation on available primitives ### Data Structures * Kernel strings: null-terminated arrays of bytes. Unsafe and to be avoided, but needed for interacting with the kernel. * Strings: length-prefixed arrays of bytes. String contents are preceded by 4 bytes (32 bytes) containing the `length` of the array. * Slices: a pair of 32-bit addresses denoting a [half-open](https://en.wikipedia.org/wiki/Interval_(mathematics)) \[`start`, `end`) interval to live memory with a consistent lifetime. Invariant: `start` <= `end` * Streams: strings prefixed by 32-bit `write` and `read` indexes that the next write or read goes to, respectively. * offset 0: write index * offset 4: read index * offset 8: length of array (in bytes) * offset 12: start of array data Invariant: 0 <= `read` <= `write` <= `length` * File descriptors (fd): Low-level 32-bit integers that the kernel uses to track files opened by the program. * File: 32-bit value containing either a fd or an address to a stream (fake file). * Buffered files (buffered-file): Contain a file descriptor and a stream for buffering reads/writes. Each `buffered-file` must exclusively perform either reads or writes. ### 'system calls' As I said at the top, a primary design goal of SubX (and Mu more broadly) is to explore ways to turn arbitrary manual tests into reproducible automated tests. SubX aims for this goal by baking testable interfaces deep into the stack, at the OS syscall level. The idea is that every syscall that interacts with hardware (and so the environment) should be *dependency injected* so that it's possible to insert fake hardware in tests. But those are big goals. Here are the syscalls I have so far: * `write`: takes two arguments, a file `f` and an address to array `s`. Comparing this interface with the Unix `write()` syscall shows two benefits: 1. SubX can handle 'fake' file descriptors in tests. 1. `write()` accepts buffer and its length in separate arguments, which requires callers to manage the two separately and so can be error-prone. SubX's wrapper keeps the two together to increase the chances that we never accidentally go out of array bounds. * `read`: takes two arguments, a file `f` and an address to stream `s`. Reads as much data from `f` as can fit in (the free space of) `s`. Like with `write()`, this wrapper around the Unix `read()` syscall adds the ability to handle 'fake' file descriptors in tests, and reduces the chances of clobbering outside array bounds. One bit of weirdness here: in tests we do a redundant copy from one stream to another. See [the comments before the implementation](http://akkartik.github.io/mu/html/060read.subx.html) for a discussion of alternative interfaces. * `stop`: takes two arguments: - `ed` is an address to an _exit descriptor_. Exit descriptors allow us to `exit()` the program in production, but return to the test harness within tests. That allows tests to make assertions about when `exit()` is called. - `value` is the status code to `exit()` with. For more details on exit descriptors and how to create one, see [the comments before the implementation](http://akkartik.github.io/mu/html/059stop.subx.html). * `new-segment` Allocates a whole new segment of memory for the program, discontiguous with both existing code and data (heap) segments. Just a more opinionated form of [`mmap`](http://man7.org/linux/man-pages/man2/mmap.2.html). * `allocate`: takes two arguments, an address to allocation-descriptor `ad` and an integer `n` Allocates a contiguous range of memory that is guaranteed to be exclusively available to the caller. Returns the starting address to the range in `eax`. An allocation descriptor tracks allocated vs available addresses in some contiguous range of memory. The int specifies the number of bytes to allocate. Explicitly passing in an allocation descriptor allows for nested memory management, where a sub-system gets a chunk of memory and further parcels it out to individual allocations. Particularly helpful for (surprise) tests. * ... _(to be continued)_ I will continue to import syscalls over time from [the old Mu VM in the parent directory](https://github.com/akkartik/mu), which has experimented with interfaces for the screen, keyboard, mouse, disk and network. ### primitives built atop system calls _(Compound arguments are usually passed in by reference. Where the results are compound objects that don't fit in a register, the caller usually passes in allocated memory for it.)_ #### assertions for tests * `check-ints-equal`: fails current test if given ints aren't equal * `check-stream-equal`: fails current test if stream doesn't match string * `check-next-stream-line-equal`: fails current test if next line of stream until newline doesn't match string #### error handling * `error`: takes three arguments, an exit-descriptor, a file and a string (message) Prints out the message to the file and then exits using the provided exit-descriptor. * `error-byte`: like `error` but takes an extra byte value that it prints out at the end of the message. #### predicates * `kernel-string-equal?`: compares a kernel string with a string * `string-equal?`: compares two strings * `stream-data-equal?`: compares a stream with a string * `next-stream-line-equal?`: compares with string the next line in a stream, from `read` index to newline * `slice-empty?`: checks if the `start` and `end` of a slice are equal * `slice-equal?`: compares a slice with a string * `slice-starts-with?`: compares the start of a slice with a string * `slice-ends-with?`: compares the end of a slice with a string #### writing to disk * `write`: string -> file - Can also be used to cat a string into a stream. - Will abort the entire program if destination is a stream and doesn't have enough room. * `write-stream`: stream -> file - Can also be used to cat one stream into another. - Will abort the entire program if destination is a stream and doesn't have enough room. * `write-slice`: slice -> stream - Will abort the entire program if there isn't enough room in the destination stream. * `append-byte`: int -> stream - Will abort the entire program if there isn't enough room in the destination stream. * `append-byte-hex`: int -> stream - textual representation in hex, no '0x' prefix - Will abort the entire program if there isn't enough room in the destination stream. * `print-int32`: int -> stream - textual representation in hex, including '0x' prefix - Will abort the entire program if there isn't enough room in the destination stream. * `write-buffered`: string -> buffered-file * `write-slice-buffered`: slice -> buffered-file * `flush`: buffered-file * `write-byte-buffered`: int -> buffered-file * `print-byte-buffered`: int -> buffered-file - textual representation in hex, no '0x' prefix * `print-int32-buffered`: int -> buffered-file - textual representation in hex, including '0x' prefix #### reading from disk * `read`: file -> stream - Can also be used to cat one stream into another. - Will silently stop reading when destination runs out of space. * `read-byte-buffered`: buffered-file -> byte * `read-line-buffered`: buffered-file -> stream - Will abort the entire program if there isn't enough room. #### non-IO operations on streams * `new-stream`: allocates space for a stream of `n` elements, each occupying `b` bytes. - Will abort the entire program if `n*b` requires more than 32 bits. * `clear-stream`: resets everything in the stream to `0` (except its `length`). * `rewind-stream`: resets the read index of the stream to `0` without modifying its contents. #### reading/writing hex representations of integers * `is-hex-int?`: takes a slice argument, returns boolean result in `eax` * `parse-hex-int`: takes a slice argument, returns int result in `eax` * `is-hex-digit?`: takes a 32-bit word containing a single byte, returns boolean result in `eax`. * `from-hex-char`: takes a hexadecimal digit character in `eax`, returns its numeric value in `eax` * `to-hex-char`: takes a single-digit numeric value in `eax`, returns its corresponding hexadecimal character in `eax` #### tokenization from a stream: * `next-token`: stream, delimiter byte -> slice * `skip-chars-matching`: stream, delimiter byte * `skip-chars-not-matching`: stream, delimiter byte from a slice: * `next-token-from-slice`: start, end, delimiter byte -> slice - Given a slice and a delimiter byte, returns a new slice inside the input that ends at the delimiter byte. * `skip-chars-matching-in-slice`: curr, end, delimiter byte -> new-curr (in `eax`) * `skip-chars-not-matching-in-slice`: curr, end, delimiter byte -> new-curr (in `eax`) ## Resources * [Single-page cheatsheet for the x86 ISA](https://net.cs.uni-bonn.de/fileadmin/user_upload/plohmann/x86_opcode_structure_and_instruction_overview.pdf) (pdf; [cached local copy](https://github.com/akkartik/mu/blob/master/cheatsheet.pdf)) * [Concise reference for the x86 ISA](https://c9x.me/x86) * [Intel processor manual](http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf) (pdf) - [&ldquo;Bootstrapping a compiler from nothing&rdquo;](http://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html) by Edmund Grumley-Evans. - [&ldquo;Creating tiny ELF executables&rdquo;](https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html) by Brian Raiter. - [StoneKnifeForth](https://github.com/kragen/stoneknifeforth) by [Kragen Sitaker](http://canonical.org/~kragen). ## Conclusion The hypothesis of Mu and SubX is that designing the entire system to be testable from day 1 and from the ground up would radically impact the culture of the eco-system in a way that no bolted-on tool or service at higher levels can replicate: * Tests would make it easier to write programs that can be easily understood by newcomers. * More broad-based understanding would lead to more forks. * Tests would make it easy to share code across forks. Copy the tests over, and then copy code over and polish it until the tests pass. Manual work, but tractable and without major risks. * The community would gain a diversified portfolio of forks for each program, a “wavefront” of possible combinations of features and alternative implementations of features. Application writers who wrote thorough tests for their apps (something they just can’t do today) would be able to bounce around between forks more easily without getting locked in to a single one as currently happens. * There would be a stronger culture of reviewing the code for programs you use or libraries you depend on. [More eyeballs would make more bugs shallow.](https://en.wikipedia.org/wiki/Linus%27s_Law) To falsify these hypotheses, here's a roadmap of the next few planned features: * Testable, dependency-injected vocabulary of primitives - Streams: `read()`, `write()`. (✓) - `exit()` (✓) - Client-like non-blocking socket/file primitives: `load`, `save` - Concurrency, and a framework for testing blocking code - Server-like blocking socket/file primitives * Gradually streamline the bundled kernel, stripping away code we don't need. --- If you're still reading, here are some more things to check out: a) Try running the tests: ```shell $ ./test_apps ``` b) Check out the online help. Try typing just `./subx`, and then `./subx help`. c) Familiarize yourself with `./subx help opcodes`. You'll spend a lot of time with it. (It's also [in this repo](https://github.com/akkartik/mu/blob/master/opcodes).) [Here](https://lobste.rs/s/qglfdp/subx_minimalist_assembly_language_for#c_o9ddqk) are some tips on my setup for quickly finding the right opcode for any situation from within Vim. d) Try working on [the starter exercises](https://github.com/akkartik/mu/pulls) (labelled `hello`). e) SubX comes with some useful [syntax sugar](http://akkartik.name/post/mu-2019-1). Check it out. ## Credits Mu builds on many ideas that have come before, especially: - [Peter Naur](http://akkartik.name/naur.pdf) for articulating the paramount problem of programming: communicating a codebase to others; - [Christopher Alexander](http://www.amazon.com/Notes-Synthesis-Form-Harvard-Paperbacks/dp/0674627512) and [Richard Gabriel](http://dreamsongs.net/Files/PatternsOfSoftware.pdf) for the intellectual tools for reasoning about the higher order design of a codebase; - Unix and C for showing us how to co-evolve language and OS, and for teaching the (much maligned, misunderstood and underestimated) value of concise *implementation* in addition to a clean interface; - Donald Knuth's [literate programming](http://www.literateprogramming.com/knuthweb.pdf) for liberating "code for humans to read" from the tyranny of compiler order; - [David Parnas](http://www.cs.umd.edu/class/spring2003/cmsc838p/Design/criteria.pdf) and others for highlighting the value of separating concerns and stepwise refinement; - [Lisp](http://www.paulgraham.com/rootsoflisp.html) for showing the power of dynamic languages, late binding and providing the right primitives *a la carte*, especially lisp macros; - The folklore of debugging by print and the trace facility in many lisp systems; - Automated tests for showing the value of developing programs inside an elaborate harness; - [Python doctest](http://docs.python.org/2/library/doctest.html) for exemplifying interactive documentation that doubles as tests; - [ReStructuredText](https://en.wikipedia.org/wiki/ReStructuredText) and [its antecedents](https://en.wikipedia.org/wiki/Setext) for showing that markup can be clean; - BDD for challenging us all to write tests at a higher level; - JavaScript and CSS for demonstrating the power of a DOM for complex structured documents; - Rust for demonstrating that a system-programming language can be safe; - Forth for demonstrating that ergonomics don't require grammar; and - [Minimal Linux Live](http://minimal.linux-bg.org) for teaching how to create a bootable disk image. - [Soso](https://github.com/ozkl/soso), a tiny hackable OS. ## Coda * [Some details on the unconventional organization of this project.](http://akkartik.name/post/four-repos) * Previous prototypes: [mu0](https://github.com/akkartik/mu0), [mu1](https://github.com/akkartik/mu1).